From: Martin Stockhammer Date: Fri, 24 Dec 2021 13:17:39 +0000 (+0100) Subject: Refactoring packages for maven repository module X-Git-Url: https://source.dussan.org/?a=commitdiff_plain;h=2507f8d057ef785ed7188122d7dc58e6a062b9ed;p=archiva.git Refactoring packages for maven repository module --- diff --git a/archiva-modules/archiva-base/archiva-consumers/archiva-core-consumers/src/test/java/org/apache/archiva/consumers/core/repository/AbstractRepositoryPurgeTest.java b/archiva-modules/archiva-base/archiva-consumers/archiva-core-consumers/src/test/java/org/apache/archiva/consumers/core/repository/AbstractRepositoryPurgeTest.java index fc4311247..fa4cee018 100644 --- a/archiva-modules/archiva-base/archiva-consumers/archiva-core-consumers/src/test/java/org/apache/archiva/consumers/core/repository/AbstractRepositoryPurgeTest.java +++ b/archiva-modules/archiva-base/archiva-consumers/archiva-core-consumers/src/test/java/org/apache/archiva/consumers/core/repository/AbstractRepositoryPurgeTest.java @@ -25,7 +25,7 @@ import org.apache.archiva.metadata.repository.RepositorySession; import org.apache.archiva.metadata.repository.RepositorySessionFactory; import org.apache.archiva.repository.ManagedRepositoryContent; import org.apache.archiva.repository.base.RepositoryHandlerDependencies; -import org.apache.archiva.repository.maven.metadata.storage.Maven2RepositoryPathTranslator; +import org.apache.archiva.maven.repository.metadata.storage.Maven2RepositoryPathTranslator; import org.apache.archiva.repository.base.managed.BasicManagedRepository; import org.apache.archiva.repository.ReleaseScheme; import org.apache.archiva.repository.RepositoryContentProvider; diff --git a/archiva-modules/archiva-maven/archiva-maven-indexer/src/test/java/org/apache/archiva/maven/indexer/MavenIndexManagerTest.java b/archiva-modules/archiva-maven/archiva-maven-indexer/src/test/java/org/apache/archiva/maven/indexer/MavenIndexManagerTest.java index 42a492267..c7e5cd55e 100644 --- a/archiva-modules/archiva-maven/archiva-maven-indexer/src/test/java/org/apache/archiva/maven/indexer/MavenIndexManagerTest.java +++ b/archiva-modules/archiva-maven/archiva-maven-indexer/src/test/java/org/apache/archiva/maven/indexer/MavenIndexManagerTest.java @@ -21,14 +21,13 @@ package org.apache.archiva.maven.indexer; import org.apache.archiva.common.utils.FileUtils; import org.apache.archiva.indexer.ArchivaIndexingContext; import org.apache.archiva.indexer.IndexCreationFailedException; -import org.apache.archiva.maven.indexer.MavenIndexManager; import org.apache.archiva.repository.RepositoryType; import org.apache.archiva.repository.base.ArchivaRepositoryRegistry; import org.apache.archiva.repository.base.RepositoryHandlerDependencies; import org.apache.archiva.repository.features.IndexCreationFeature; import org.apache.archiva.repository.features.RemoteIndexFeature; -import org.apache.archiva.repository.maven.MavenManagedRepository; -import org.apache.archiva.repository.maven.MavenRemoteRepository; +import org.apache.archiva.maven.repository.MavenManagedRepository; +import org.apache.archiva.maven.repository.MavenRemoteRepository; import org.apache.archiva.test.utils.ArchivaSpringJUnit4ClassRunner; import org.apache.maven.index.MAVEN; import org.apache.maven.index.QueryCreator; diff --git a/archiva-modules/archiva-maven/archiva-maven-repository/src/main/java/org/apache/archiva/maven/repository/MavenManagedRepository.java b/archiva-modules/archiva-maven/archiva-maven-repository/src/main/java/org/apache/archiva/maven/repository/MavenManagedRepository.java new file mode 100644 index 000000000..5e81f868a --- /dev/null +++ b/archiva-modules/archiva-maven/archiva-maven-repository/src/main/java/org/apache/archiva/maven/repository/MavenManagedRepository.java @@ -0,0 +1,146 @@ +package org.apache.archiva.maven.repository; + +/* + * 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.filelock.DefaultFileLockManager; +import org.apache.archiva.common.filelock.FileLockManager; +import org.apache.archiva.indexer.ArchivaIndexingContext; +import org.apache.archiva.maven.repository.content.MavenRepositoryRequestInfo; +import org.apache.archiva.repository.ReleaseScheme; +import org.apache.archiva.repository.RepositoryCapabilities; +import org.apache.archiva.repository.RepositoryRequestInfo; +import org.apache.archiva.repository.RepositoryState; +import org.apache.archiva.repository.RepositoryType; +import org.apache.archiva.repository.StandardCapabilities; +import org.apache.archiva.repository.UnsupportedFeatureException; +import org.apache.archiva.repository.base.managed.AbstractManagedRepository; +import org.apache.archiva.repository.features.ArtifactCleanupFeature; +import org.apache.archiva.repository.features.IndexCreationFeature; +import org.apache.archiva.repository.features.RepositoryFeature; +import org.apache.archiva.repository.features.StagingRepositoryFeature; +import org.apache.archiva.repository.storage.fs.FilesystemStorage; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.io.IOException; +import java.nio.file.Path; +import java.util.Locale; + +/** + * Maven2 managed repository implementation. + */ +public class MavenManagedRepository extends AbstractManagedRepository +{ + + private static final Logger log = LoggerFactory.getLogger( MavenManagedRepository.class ); + + public static final String DEFAULT_LAYOUT = "default"; + public static final String LEGACY_LAYOUT = "legacy"; + private ArtifactCleanupFeature artifactCleanupFeature = new ArtifactCleanupFeature( ); + private IndexCreationFeature indexCreationFeature; + private StagingRepositoryFeature stagingRepositoryFeature = new StagingRepositoryFeature( ); + + + + private static final RepositoryCapabilities CAPABILITIES = new StandardCapabilities( + new ReleaseScheme[] { ReleaseScheme.RELEASE, ReleaseScheme.SNAPSHOT }, + new String[] { DEFAULT_LAYOUT, LEGACY_LAYOUT}, + new String[] {}, + new String[] {ArtifactCleanupFeature.class.getName(), IndexCreationFeature.class.getName(), + StagingRepositoryFeature.class.getName()}, + true, + true, + true, + true, + false + ); + + public MavenManagedRepository(String id, String name, FilesystemStorage storage) + { + + super( RepositoryType.MAVEN, id, name, storage); + this.indexCreationFeature = new IndexCreationFeature(this, this); + setLocation(storage.getRoot().getFilePath().toUri()); + setLastState( RepositoryState.CREATED ); + } + + public MavenManagedRepository( Locale primaryLocale, String id, String name, FilesystemStorage storage ) + { + super( primaryLocale, RepositoryType.MAVEN, id, name, storage ); + setLocation(storage.getRoot().getFilePath().toUri()); + setLastState( RepositoryState.CREATED ); + } + + @Override + public RepositoryCapabilities getCapabilities( ) + { + return CAPABILITIES; + } + + + @SuppressWarnings( "unchecked" ) + @Override + public > RepositoryFeature getFeature( Class clazz ) throws UnsupportedFeatureException + { + if (ArtifactCleanupFeature.class.equals( clazz )) + { + return (RepositoryFeature) artifactCleanupFeature; + } else if (IndexCreationFeature.class.equals(clazz)) { + return (RepositoryFeature) indexCreationFeature; + } else if (StagingRepositoryFeature.class.equals(clazz)) { + return (RepositoryFeature) stagingRepositoryFeature; + } else { + throw new UnsupportedFeatureException( ); + } + } + + @Override + public > boolean supportsFeature( Class clazz ) + { + if (ArtifactCleanupFeature.class.equals(clazz) || + IndexCreationFeature.class.equals(clazz) || + StagingRepositoryFeature.class.equals(clazz)) { + return true; + } + return false; + } + + @Override + public boolean hasIndex( ) + { + return indexCreationFeature.hasIndex(); + } + + @Override + public RepositoryRequestInfo getRequestInfo() { + return new MavenRepositoryRequestInfo(this); + } + + public static MavenManagedRepository newLocalInstance(String id, String name, Path basePath) throws IOException { + FileLockManager lockManager = new DefaultFileLockManager(); + FilesystemStorage storage = new FilesystemStorage(basePath.resolve(id), lockManager); + return new MavenManagedRepository(id, name, storage); + } + + @Override + public void setIndexingContext(ArchivaIndexingContext context) { + super.setIndexingContext(context); + } + +} diff --git a/archiva-modules/archiva-maven/archiva-maven-repository/src/main/java/org/apache/archiva/maven/repository/MavenRemoteRepository.java b/archiva-modules/archiva-maven/archiva-maven-repository/src/main/java/org/apache/archiva/maven/repository/MavenRemoteRepository.java new file mode 100644 index 000000000..1be681ece --- /dev/null +++ b/archiva-modules/archiva-maven/archiva-maven-repository/src/main/java/org/apache/archiva/maven/repository/MavenRemoteRepository.java @@ -0,0 +1,125 @@ +package org.apache.archiva.maven.repository; + +import org.apache.archiva.common.filelock.DefaultFileLockManager; +import org.apache.archiva.common.filelock.FileLockManager; +import org.apache.archiva.repository.ReleaseScheme; +import org.apache.archiva.repository.RemoteRepository; +import org.apache.archiva.repository.RepositoryCapabilities; +import org.apache.archiva.repository.RepositoryState; +import org.apache.archiva.repository.RepositoryType; +import org.apache.archiva.repository.StandardCapabilities; +import org.apache.archiva.repository.UnsupportedFeatureException; +import org.apache.archiva.repository.base.remote.AbstractRemoteRepository; +import org.apache.archiva.repository.features.IndexCreationFeature; +import org.apache.archiva.repository.features.RemoteIndexFeature; +import org.apache.archiva.repository.features.RepositoryFeature; +import org.apache.archiva.repository.storage.fs.FilesystemStorage; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.io.IOException; +import java.nio.file.Path; +import java.util.Locale; + +/* + * 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. + */ + +/** + * Maven2 remote repository implementation + */ +public class MavenRemoteRepository extends AbstractRemoteRepository + implements RemoteRepository +{ + + Logger log = LoggerFactory.getLogger(MavenRemoteRepository.class); + + final private RemoteIndexFeature remoteIndexFeature = new RemoteIndexFeature(); + final private IndexCreationFeature indexCreationFeature; + + private static final RepositoryCapabilities CAPABILITIES = new StandardCapabilities( + new ReleaseScheme[] { ReleaseScheme.RELEASE, ReleaseScheme.SNAPSHOT }, + new String[] { MavenManagedRepository.DEFAULT_LAYOUT, MavenManagedRepository.LEGACY_LAYOUT}, + new String[] {}, + new String[] {RemoteIndexFeature.class.getName(), IndexCreationFeature.class.getName()}, + true, + true, + true, + true, + false + ); + + public MavenRemoteRepository(String id, String name, FilesystemStorage storage) + { + super( RepositoryType.MAVEN, id, name, storage ); + this.indexCreationFeature = new IndexCreationFeature(this, this); + setLastState( RepositoryState.CREATED ); + } + + public MavenRemoteRepository( Locale primaryLocale, String id, String name, FilesystemStorage storage ) + { + super( primaryLocale, RepositoryType.MAVEN, id, name, storage ); + this.indexCreationFeature = new IndexCreationFeature(this, this); + setLastState( RepositoryState.CREATED ); + } + + @Override + public boolean hasIndex( ) + { + return remoteIndexFeature.hasIndex(); + } + + @Override + public RepositoryCapabilities getCapabilities( ) + { + return CAPABILITIES; + } + + @SuppressWarnings( "unchecked" ) + @Override + public > RepositoryFeature getFeature( Class clazz ) throws UnsupportedFeatureException + { + if (RemoteIndexFeature.class.equals( clazz )) { + return (RepositoryFeature) remoteIndexFeature; + } else if (IndexCreationFeature.class.equals(clazz)) { + return (RepositoryFeature) indexCreationFeature; + } else { + throw new UnsupportedFeatureException( ); + } + } + + @Override + public > boolean supportsFeature( Class clazz ) + { + if ( RemoteIndexFeature.class.equals(clazz) || IndexCreationFeature.class.equals(clazz)) { + return true; + } else { + return false; + } + } + + @Override + public String toString() { + return super.toString()+", remoteIndexFeature="+remoteIndexFeature.toString()+", indexCreationFeature="+indexCreationFeature.toString(); + } + + public static MavenRemoteRepository newLocalInstance(String id, String name, Path basePath) throws IOException { + FileLockManager lockManager = new DefaultFileLockManager(); + FilesystemStorage storage = new FilesystemStorage(basePath.resolve(id), lockManager); + return new MavenRemoteRepository(id, name, storage); + } +} diff --git a/archiva-modules/archiva-maven/archiva-maven-repository/src/main/java/org/apache/archiva/maven/repository/MavenRepositoryGroup.java b/archiva-modules/archiva-maven/archiva-maven-repository/src/main/java/org/apache/archiva/maven/repository/MavenRepositoryGroup.java new file mode 100644 index 000000000..f24c67566 --- /dev/null +++ b/archiva-modules/archiva-maven/archiva-maven-repository/src/main/java/org/apache/archiva/maven/repository/MavenRepositoryGroup.java @@ -0,0 +1,85 @@ +package org.apache.archiva.maven.repository; + +/* + * 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.filelock.DefaultFileLockManager; +import org.apache.archiva.common.filelock.FileLockManager; +import org.apache.archiva.repository.EditableRepositoryGroup; +import org.apache.archiva.repository.ReleaseScheme; +import org.apache.archiva.repository.RepositoryCapabilities; +import org.apache.archiva.repository.RepositoryState; +import org.apache.archiva.repository.RepositoryType; +import org.apache.archiva.repository.StandardCapabilities; +import org.apache.archiva.repository.base.group.AbstractRepositoryGroup; +import org.apache.archiva.repository.features.IndexCreationFeature; +import org.apache.archiva.repository.storage.fs.FilesystemStorage; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.io.IOException; +import java.nio.file.Path; +import java.util.Locale; + +public class MavenRepositoryGroup extends AbstractRepositoryGroup implements EditableRepositoryGroup { + + private static final RepositoryCapabilities CAPABILITIES = new StandardCapabilities( + new ReleaseScheme[] { ReleaseScheme.RELEASE, ReleaseScheme.SNAPSHOT }, + new String[] { MavenManagedRepository.DEFAULT_LAYOUT, MavenManagedRepository.LEGACY_LAYOUT}, + new String[] {}, + new String[] {IndexCreationFeature.class.getName()}, + false, + false, + false, + false, + false + ); + + private final Logger log = LoggerFactory.getLogger(MavenRepositoryGroup.class); + + private IndexCreationFeature indexCreationFeature; + + + public MavenRepositoryGroup(String id, String name, FilesystemStorage storage) { + super(RepositoryType.MAVEN, id, name, storage); + init(); + setLastState( RepositoryState.CREATED ); + } + + public MavenRepositoryGroup(Locale primaryLocale, String id, String name, FilesystemStorage storage) { + super(primaryLocale, RepositoryType.MAVEN, id, name, storage); + init(); + setLastState( RepositoryState.CREATED ); + } + + private Path getRepositoryPath() { + return getStorage().getRoot().getFilePath(); + } + + private void init() { + setCapabilities(CAPABILITIES); + this.indexCreationFeature = new IndexCreationFeature(this, this); + addFeature( this.indexCreationFeature ); + } + + public static MavenRepositoryGroup newLocalInstance(String id, String name, Path basePath) throws IOException { + FileLockManager lockManager = new DefaultFileLockManager(); + FilesystemStorage storage = new FilesystemStorage(basePath.resolve(id), lockManager); + return new MavenRepositoryGroup(id, name, storage); + } +} diff --git a/archiva-modules/archiva-maven/archiva-maven-repository/src/main/java/org/apache/archiva/maven/repository/MavenRepositoryProvider.java b/archiva-modules/archiva-maven/archiva-maven-repository/src/main/java/org/apache/archiva/maven/repository/MavenRepositoryProvider.java new file mode 100644 index 000000000..636b8c988 --- /dev/null +++ b/archiva-modules/archiva-maven/archiva-maven-repository/src/main/java/org/apache/archiva/maven/repository/MavenRepositoryProvider.java @@ -0,0 +1,574 @@ +package org.apache.archiva.maven.repository; + +/* + * 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.filelock.FileLockManager; +import org.apache.archiva.configuration.AbstractRepositoryConfiguration; +import org.apache.archiva.configuration.ArchivaConfiguration; +import org.apache.archiva.configuration.ManagedRepositoryConfiguration; +import org.apache.archiva.configuration.RemoteRepositoryConfiguration; +import org.apache.archiva.configuration.RepositoryGroupConfiguration; +import org.apache.archiva.event.Event; +import org.apache.archiva.event.EventHandler; +import org.apache.archiva.repository.EditableManagedRepository; +import org.apache.archiva.repository.EditableRemoteRepository; +import org.apache.archiva.repository.EditableRepository; +import org.apache.archiva.repository.EditableRepositoryGroup; +import org.apache.archiva.repository.ManagedRepository; +import org.apache.archiva.repository.ReleaseScheme; +import org.apache.archiva.repository.RemoteRepository; +import org.apache.archiva.repository.Repository; +import org.apache.archiva.repository.RepositoryCredentials; +import org.apache.archiva.repository.RepositoryException; +import org.apache.archiva.repository.RepositoryGroup; +import org.apache.archiva.repository.RepositoryProvider; +import org.apache.archiva.repository.RepositoryType; +import org.apache.archiva.repository.UnsupportedURIException; +import org.apache.archiva.repository.base.managed.BasicManagedRepository; +import org.apache.archiva.repository.base.PasswordCredentials; +import org.apache.archiva.repository.event.RepositoryEvent; +import org.apache.archiva.repository.features.ArtifactCleanupFeature; +import org.apache.archiva.repository.features.IndexCreationFeature; +import org.apache.archiva.repository.features.RemoteIndexFeature; +import org.apache.archiva.repository.features.StagingRepositoryFeature; +import org.apache.archiva.repository.storage.fs.FilesystemStorage; +import org.apache.commons.lang3.StringUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.stereotype.Service; + +import javax.inject.Inject; +import java.io.IOException; +import java.net.URI; +import java.net.URISyntaxException; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.time.Duration; +import java.time.Period; +import java.time.temporal.ChronoUnit; +import java.util.ArrayList; +import java.util.HashSet; +import java.util.List; +import java.util.Set; +import java.util.stream.Collectors; + +import static org.apache.archiva.indexer.ArchivaIndexManager.DEFAULT_INDEX_PATH; +import static org.apache.archiva.indexer.ArchivaIndexManager.DEFAULT_PACKED_INDEX_PATH; + +/** + * Provider for the maven2 repository implementation + */ +@Service("mavenRepositoryProvider") +public class MavenRepositoryProvider implements RepositoryProvider { + + + @Inject + private ArchivaConfiguration archivaConfiguration; + + @Inject + private FileLockManager fileLockManager; + + private final List> repositoryEventHandlers = new ArrayList<>( ); + + private static final Logger log = LoggerFactory.getLogger(MavenRepositoryProvider.class); + + static final Set TYPES = new HashSet<>(); + + static { + TYPES.add(RepositoryType.MAVEN); + } + + @Override + public Set provides() { + return TYPES; + } + + @Override + public MavenManagedRepository createManagedInstance(String id, String name) { + return createManagedInstance(id, name, archivaConfiguration.getRemoteRepositoryBaseDir()); + } + + public MavenManagedRepository createManagedInstance(String id, String name, Path baseDir) { + FilesystemStorage storage; + try { + storage = new FilesystemStorage(baseDir.resolve(id), fileLockManager); + } catch (IOException e) { + log.error("Could not initialize fileystem for repository {}", id); + throw new RuntimeException(e); + } + MavenManagedRepository repo = new MavenManagedRepository( id, name, storage ); + registerEventHandler( repo ); + return repo; + } + + @Override + public MavenRemoteRepository createRemoteInstance(String id, String name) { + return createRemoteInstance(id, name, archivaConfiguration.getRemoteRepositoryBaseDir()); + } + + public MavenRemoteRepository createRemoteInstance(String id, String name, Path baseDir) { + FilesystemStorage storage; + try { + storage = new FilesystemStorage(baseDir.resolve(id), fileLockManager); + } catch (IOException e) { + log.error("Could not initialize filesystem for repository {}: '{}'", id, e.getMessage()); + throw new RuntimeException(e); + } + MavenRemoteRepository repo = new MavenRemoteRepository( id, name, storage ); + registerEventHandler( repo ); + return repo; + } + + @Override + public EditableRepositoryGroup createRepositoryGroup(String id, String name) { + return createRepositoryGroup(id, name, archivaConfiguration.getRepositoryGroupBaseDir().resolve( id )); + } + + public MavenRepositoryGroup createRepositoryGroup(String id, String name, Path repositoryPath) { + FilesystemStorage storage; + try { + storage = new FilesystemStorage(repositoryPath, fileLockManager); + } catch (IOException e) { + log.error("Could not initialize filesystem for repository {}: '{}'", id, e.getMessage()); + throw new RuntimeException(e); + } + MavenRepositoryGroup group = new MavenRepositoryGroup( id, name, storage ); + registerEventHandler( group ); + return group; + } + + private void registerEventHandler( Repository repo ) { + for (EventHandler eventHandler : repositoryEventHandlers) { + repo.registerEventHandler( RepositoryEvent.ANY, eventHandler ); + } + } + + private URI getURIFromString(String uriStr) throws RepositoryException { + URI uri; + try { + if (StringUtils.isEmpty(uriStr)) { + return new URI(""); + } + if (uriStr.startsWith("/")) { + // only absolute paths are prepended with file scheme + uri = new URI("file://" + uriStr); + } else if (uriStr.contains(":\\")) { + //windows absolute path drive + uri = new URI("file:///" + uriStr.replaceAll("\\\\", "/")); + } else { + uri = new URI(uriStr); + } + if (uri.getScheme() != null && !"file".equals(uri.getScheme())) { + log.error("Bad URI scheme found: {}, URI={}", uri.getScheme(), uri); + throw new RepositoryException("The uri " + uriStr + " is not valid. Only file:// URI is allowed for maven."); + } + } catch (URISyntaxException e) { + String newCfg = "file://" + uriStr; + try { + uri = new URI(newCfg); + } catch (URISyntaxException e1) { + log.error("Could not create URI from {} -> {}", uriStr, newCfg); + throw new RepositoryException("The config entry " + uriStr + " cannot be converted to URI."); + } + } + log.debug("Setting location uri: {}", uri); + return uri; + } + + @Override + public ManagedRepository createManagedInstance(ManagedRepositoryConfiguration cfg) throws RepositoryException { + MavenManagedRepository repo = createManagedInstance(cfg.getId(), cfg.getName(), Paths.get(cfg.getLocation()).getParent()); + updateManagedInstance(repo, cfg); + return repo; + } + + @Override + public void updateManagedInstance(EditableManagedRepository repo, ManagedRepositoryConfiguration cfg) throws RepositoryException { + try { + repo.setLocation(getURIFromString(cfg.getLocation())); + } catch (UnsupportedURIException e) { + throw new RepositoryException("The location entry is not a valid uri: " + cfg.getLocation()); + } + setBaseConfig(repo, cfg); + Path repoDir = repo.getRoot().getFilePath(); + if (!Files.exists(repoDir)) { + log.debug("Creating repo directory {}", repoDir); + try { + Files.createDirectories(repoDir); + } catch (IOException e) { + log.error("Could not create directory {} for repository {}", repoDir, repo.getId(), e); + throw new RepositoryException("Could not create directory for repository " + repoDir); + } + } + repo.setSchedulingDefinition(cfg.getRefreshCronExpression()); + repo.setBlocksRedeployment(cfg.isBlockRedeployments()); + repo.setScanned(cfg.isScanned()); + if (cfg.isReleases()) { + repo.addActiveReleaseScheme(ReleaseScheme.RELEASE); + } else { + repo.removeActiveReleaseScheme(ReleaseScheme.RELEASE); + } + if (cfg.isSnapshots()) { + repo.addActiveReleaseScheme(ReleaseScheme.SNAPSHOT); + } else { + repo.removeActiveReleaseScheme(ReleaseScheme.SNAPSHOT); + } + + StagingRepositoryFeature stagingRepositoryFeature = repo.getFeature(StagingRepositoryFeature.class).get(); + stagingRepositoryFeature.setStageRepoNeeded(cfg.isStageRepoNeeded()); + + IndexCreationFeature indexCreationFeature = repo.getFeature(IndexCreationFeature.class).get(); + indexCreationFeature.setSkipPackedIndexCreation(cfg.isSkipPackedIndexCreation()); + String indexDir = StringUtils.isEmpty( cfg.getIndexDir() ) ? DEFAULT_INDEX_PATH : cfg.getIndexDir(); + String packedIndexDir = StringUtils.isEmpty( cfg.getPackedIndexDir() ) ? DEFAULT_PACKED_INDEX_PATH : cfg.getPackedIndexDir(); + indexCreationFeature.setIndexPath(getURIFromString(indexDir)); + indexCreationFeature.setPackedIndexPath(getURIFromString(packedIndexDir)); + + ArtifactCleanupFeature artifactCleanupFeature = repo.getFeature(ArtifactCleanupFeature.class).get(); + + artifactCleanupFeature.setDeleteReleasedSnapshots(cfg.isDeleteReleasedSnapshots()); + artifactCleanupFeature.setRetentionCount(cfg.getRetentionCount()); + artifactCleanupFeature.setRetentionPeriod(Period.ofDays(cfg.getRetentionPeriod())); + } + + + @Override + public ManagedRepository createStagingInstance(ManagedRepositoryConfiguration baseConfiguration) throws RepositoryException { + log.debug("Creating staging instance for {}", baseConfiguration.getId()); + return createManagedInstance(getStageRepoConfig(baseConfiguration)); + } + + + @Override + public RemoteRepository createRemoteInstance(RemoteRepositoryConfiguration cfg) throws RepositoryException { + MavenRemoteRepository repo = createRemoteInstance(cfg.getId(), cfg.getName(), archivaConfiguration.getRemoteRepositoryBaseDir()); + updateRemoteInstance(repo, cfg); + return repo; + } + + private String convertUriToPath(URI uri) { + if (uri.getScheme() == null) { + return uri.getPath(); + } else if ("file".equals(uri.getScheme())) { + return Paths.get(uri).toString(); + } else { + return uri.toString(); + } + } + + @Override + public void updateRemoteInstance(EditableRemoteRepository repo, RemoteRepositoryConfiguration cfg) throws RepositoryException { + setBaseConfig(repo, cfg); + repo.setCheckPath(cfg.getCheckPath()); + repo.setSchedulingDefinition(cfg.getRefreshCronExpression()); + try { + repo.setLocation(new URI(cfg.getUrl())); + } catch (UnsupportedURIException | URISyntaxException e) { + log.error("Could not set remote url " + cfg.getUrl()); + throw new RepositoryException("The url config is not a valid uri: " + cfg.getUrl()); + } + repo.setTimeout(Duration.ofSeconds(cfg.getTimeout())); + RemoteIndexFeature remoteIndexFeature = repo.getFeature(RemoteIndexFeature.class).get(); + remoteIndexFeature.setDownloadRemoteIndex(cfg.isDownloadRemoteIndex()); + remoteIndexFeature.setDownloadRemoteIndexOnStartup(cfg.isDownloadRemoteIndexOnStartup()); + remoteIndexFeature.setDownloadTimeout(Duration.ofSeconds(cfg.getRemoteDownloadTimeout())); + remoteIndexFeature.setProxyId(cfg.getRemoteDownloadNetworkProxyId()); + if (cfg.isDownloadRemoteIndex()) { + try { + remoteIndexFeature.setIndexUri(new URI(cfg.getRemoteIndexUrl())); + } catch (URISyntaxException e) { + log.error("Could not set remote index url " + cfg.getRemoteIndexUrl()); + remoteIndexFeature.setDownloadRemoteIndex(false); + remoteIndexFeature.setDownloadRemoteIndexOnStartup(false); + } + } + for ( Object key : cfg.getExtraHeaders().keySet() ) { + repo.addExtraHeader( key.toString(), cfg.getExtraHeaders().get(key).toString() ); + } + for ( Object key : cfg.getExtraParameters().keySet() ) { + repo.addExtraParameter( key.toString(), cfg.getExtraParameters().get(key).toString() ); + } + PasswordCredentials credentials = new PasswordCredentials("", new char[0]); + if (cfg.getPassword() != null && cfg.getUsername() != null) { + credentials.setPassword(cfg.getPassword().toCharArray()); + credentials.setUsername(cfg.getUsername()); + repo.setCredentials(credentials); + } else { + credentials.setPassword(new char[0]); + } + IndexCreationFeature indexCreationFeature = repo.getFeature(IndexCreationFeature.class).get(); + if ( !StringUtils.isEmpty( cfg.getIndexDir( ) ) ) + { + indexCreationFeature.setIndexPath( getURIFromString( cfg.getIndexDir( ) ) ); + } + if (!StringUtils.isEmpty( cfg.getPackedIndexDir() )) { + indexCreationFeature.setPackedIndexPath(getURIFromString(cfg.getPackedIndexDir())); + } + log.debug("Updated remote instance {}", repo); + } + + @Override + public RepositoryGroup createRepositoryGroup(RepositoryGroupConfiguration configuration) throws RepositoryException { + Path repositoryPath = getRepositoryGroupPath( configuration ); + MavenRepositoryGroup newGrp = createRepositoryGroup(configuration.getId(), configuration.getName(), + repositoryPath); + updateRepositoryGroupInstance(newGrp, configuration); + return newGrp; + } + + private Path getRepositoryGroupPath(RepositoryGroupConfiguration configuration) { + if (StringUtils.isNotEmpty( configuration.getLocation() )) { + return Paths.get( configuration.getLocation( ) ); + } else { + return getArchivaConfiguration( ).getRepositoryGroupBaseDir( ).resolve( configuration.getId( ) ); + } + } + + @Override + public void updateRepositoryGroupInstance(EditableRepositoryGroup repositoryGroup, RepositoryGroupConfiguration configuration) throws RepositoryException { + repositoryGroup.setName(repositoryGroup.getPrimaryLocale(), configuration.getName()); + repositoryGroup.setMergedIndexTTL(configuration.getMergedIndexTtl()); + repositoryGroup.setSchedulingDefinition(configuration.getCronExpression()); + if (repositoryGroup.supportsFeature( IndexCreationFeature.class )) { + IndexCreationFeature indexCreationFeature = repositoryGroup.getFeature( IndexCreationFeature.class ).get(); + indexCreationFeature.setIndexPath( getURIFromString(configuration.getMergedIndexPath()) ); + Path localPath = Paths.get(configuration.getMergedIndexPath()); + Path repoGroupPath = repositoryGroup.getRoot().getFilePath().toAbsolutePath(); + if (localPath.isAbsolute() && !localPath.startsWith(repoGroupPath)) { + try { + FilesystemStorage storage = new FilesystemStorage(localPath.getParent(), fileLockManager); + indexCreationFeature.setLocalIndexPath(storage.getAsset(localPath.getFileName().toString())); + } catch (IOException e) { + throw new RepositoryException("Could not initialize storage for index path "+localPath); + } + } else if (localPath.isAbsolute()) { + indexCreationFeature.setLocalIndexPath(repositoryGroup.getAsset(repoGroupPath.relativize(localPath).toString())); + } else + { + indexCreationFeature.setLocalIndexPath(repositoryGroup.getAsset(localPath.toString())); + } + } + // References to other repositories are set filled by the registry + } + + @Override + public RemoteRepositoryConfiguration getRemoteConfiguration(RemoteRepository remoteRepository) throws RepositoryException { + if (!(remoteRepository instanceof MavenRemoteRepository)) { + log.error("Wrong remote repository type " + remoteRepository.getClass().getName()); + throw new RepositoryException("The given repository type cannot be handled by the maven provider: " + remoteRepository.getClass().getName()); + } + RemoteRepositoryConfiguration cfg = new RemoteRepositoryConfiguration(); + cfg.setType(remoteRepository.getType().toString()); + cfg.setId(remoteRepository.getId()); + cfg.setName(remoteRepository.getName()); + cfg.setDescription(remoteRepository.getDescription()); + cfg.setUrl(remoteRepository.getLocation().toString()); + cfg.setTimeout((int) remoteRepository.getTimeout().toMillis() / 1000); + cfg.setCheckPath(remoteRepository.getCheckPath()); + RepositoryCredentials creds = remoteRepository.getLoginCredentials(); + if (creds != null) { + if (creds instanceof PasswordCredentials) { + PasswordCredentials pCreds = (PasswordCredentials) creds; + cfg.setPassword(new String(pCreds.getPassword())); + cfg.setUsername(pCreds.getUsername()); + } + } + cfg.setLayout(remoteRepository.getLayout()); + cfg.setExtraParameters(remoteRepository.getExtraParameters()); + cfg.setExtraHeaders(remoteRepository.getExtraHeaders()); + cfg.setRefreshCronExpression(remoteRepository.getSchedulingDefinition()); + + IndexCreationFeature indexCreationFeature = remoteRepository.getFeature(IndexCreationFeature.class).get(); + cfg.setIndexDir(convertUriToPath(indexCreationFeature.getIndexPath())); + cfg.setPackedIndexDir(convertUriToPath(indexCreationFeature.getPackedIndexPath())); + + RemoteIndexFeature remoteIndexFeature = remoteRepository.getFeature(RemoteIndexFeature.class).get(); + if ( remoteIndexFeature.getIndexUri( ) == null ) + { + cfg.setRemoteIndexUrl( "" ); + } + else + { + cfg.setRemoteIndexUrl(remoteIndexFeature.getIndexUri().toString()); + } + cfg.setRemoteDownloadTimeout((int) remoteIndexFeature.getDownloadTimeout().get(ChronoUnit.SECONDS)); + cfg.setDownloadRemoteIndexOnStartup(remoteIndexFeature.isDownloadRemoteIndexOnStartup()); + cfg.setDownloadRemoteIndex(remoteIndexFeature.isDownloadRemoteIndex()); + cfg.setRemoteDownloadNetworkProxyId(remoteIndexFeature.getProxyId()); + if ( StringUtils.isEmpty( remoteIndexFeature.getProxyId( ) ) ) + { + cfg.setRemoteDownloadNetworkProxyId(""); + } + else + { + cfg.setRemoteDownloadNetworkProxyId(remoteIndexFeature.getProxyId()); + } + + + return cfg; + + } + + @Override + public ManagedRepositoryConfiguration getManagedConfiguration(ManagedRepository managedRepository) throws RepositoryException { + if (!(managedRepository instanceof MavenManagedRepository || managedRepository instanceof BasicManagedRepository )) { + log.error("Wrong remote repository type " + managedRepository.getClass().getName()); + throw new RepositoryException("The given repository type cannot be handled by the maven provider: " + managedRepository.getClass().getName()); + } + ManagedRepositoryConfiguration cfg = new ManagedRepositoryConfiguration(); + cfg.setType(managedRepository.getType().toString()); + cfg.setId(managedRepository.getId()); + cfg.setName(managedRepository.getName()); + cfg.setDescription(managedRepository.getDescription()); + cfg.setLocation(convertUriToPath(managedRepository.getLocation())); + cfg.setLayout(managedRepository.getLayout()); + cfg.setRefreshCronExpression(managedRepository.getSchedulingDefinition()); + cfg.setScanned(managedRepository.isScanned()); + cfg.setBlockRedeployments(managedRepository.blocksRedeployments()); + StagingRepositoryFeature stagingRepositoryFeature = managedRepository.getFeature(StagingRepositoryFeature.class).get(); + cfg.setStageRepoNeeded(stagingRepositoryFeature.isStageRepoNeeded()); + IndexCreationFeature indexCreationFeature = managedRepository.getFeature(IndexCreationFeature.class).get(); + cfg.setIndexDir(convertUriToPath(indexCreationFeature.getIndexPath())); + cfg.setPackedIndexDir(convertUriToPath(indexCreationFeature.getPackedIndexPath())); + cfg.setSkipPackedIndexCreation(indexCreationFeature.isSkipPackedIndexCreation()); + + ArtifactCleanupFeature artifactCleanupFeature = managedRepository.getFeature(ArtifactCleanupFeature.class).get(); + cfg.setRetentionCount(artifactCleanupFeature.getRetentionCount()); + cfg.setRetentionPeriod(artifactCleanupFeature.getRetentionPeriod().getDays()); + cfg.setDeleteReleasedSnapshots(artifactCleanupFeature.isDeleteReleasedSnapshots()); + + cfg.setReleases( managedRepository.getActiveReleaseSchemes( ).contains( ReleaseScheme.RELEASE ) ); + cfg.setSnapshots( managedRepository.getActiveReleaseSchemes( ).contains( ReleaseScheme.SNAPSHOT ) ); + return cfg; + + } + + @Override + public RepositoryGroupConfiguration getRepositoryGroupConfiguration(RepositoryGroup repositoryGroup) throws RepositoryException { + if (repositoryGroup.getType() != RepositoryType.MAVEN) { + throw new RepositoryException("The given repository group is not of MAVEN type"); + } + RepositoryGroupConfiguration cfg = new RepositoryGroupConfiguration(); + cfg.setId(repositoryGroup.getId()); + cfg.setName(repositoryGroup.getName()); + if (repositoryGroup.supportsFeature( IndexCreationFeature.class )) + { + IndexCreationFeature indexCreationFeature = repositoryGroup.getFeature( IndexCreationFeature.class ).get(); + + cfg.setMergedIndexPath( indexCreationFeature.getIndexPath().toString() ); + } + cfg.setMergedIndexTtl(repositoryGroup.getMergedIndexTTL()); + cfg.setRepositories(repositoryGroup.getRepositories().stream().map( Repository::getId ).collect(Collectors.toList())); + cfg.setCronExpression(repositoryGroup.getSchedulingDefinition()); + return cfg; + } + + @Override + public void addRepositoryEventHandler( EventHandler eventHandler ) + { + this.repositoryEventHandlers.add( eventHandler ); + } + + private ManagedRepositoryConfiguration getStageRepoConfig(ManagedRepositoryConfiguration repository) { + ManagedRepositoryConfiguration stagingRepository = new ManagedRepositoryConfiguration(); + stagingRepository.setId(repository.getId() + StagingRepositoryFeature.STAGING_REPO_POSTFIX); + stagingRepository.setLayout(repository.getLayout()); + stagingRepository.setName(repository.getName() + StagingRepositoryFeature.STAGING_REPO_POSTFIX); + stagingRepository.setBlockRedeployments(repository.isBlockRedeployments()); + stagingRepository.setRetentionPeriod(repository.getRetentionPeriod()); + stagingRepository.setDeleteReleasedSnapshots(repository.isDeleteReleasedSnapshots()); + stagingRepository.setStageRepoNeeded(false); + + String path = repository.getLocation(); + int lastIndex = path.replace('\\', '/').lastIndexOf('/'); + stagingRepository.setLocation(path.substring(0, lastIndex) + "/" + stagingRepository.getId()); + + if (StringUtils.isNotBlank(repository.getIndexDir())) { + Path indexDir; + try { + if (repository.getIndexDir().startsWith( "file:" )) { + indexDir = Paths.get( new URI( repository.getIndexDir( ) ) ); + } else + { + indexDir = Paths.get( repository.getIndexDir( ) ); + } + if (indexDir.isAbsolute()) { + Path newDir = indexDir.getParent().resolve(indexDir.getFileName() + StagingRepositoryFeature.STAGING_REPO_POSTFIX); + log.debug("Changing index directory {} -> {}", indexDir, newDir); + stagingRepository.setIndexDir(newDir.toString()); + } else { + log.debug("Keeping index directory {}", repository.getIndexDir()); + stagingRepository.setIndexDir(repository.getIndexDir()); + } + } catch (URISyntaxException e) { + log.error("Could not parse index path as uri {}", repository.getIndexDir()); + stagingRepository.setIndexDir(""); + } + // in case of absolute dir do not use the same + } + if (StringUtils.isNotBlank(repository.getPackedIndexDir())) { + Path packedIndexDir; + packedIndexDir = Paths.get(repository.getPackedIndexDir()); + if (packedIndexDir.isAbsolute()) { + Path newDir = packedIndexDir.getParent().resolve(packedIndexDir.getFileName() + StagingRepositoryFeature.STAGING_REPO_POSTFIX); + log.debug("Changing index directory {} -> {}", packedIndexDir, newDir); + stagingRepository.setPackedIndexDir(newDir.toString()); + } else { + log.debug("Keeping index directory {}", repository.getPackedIndexDir()); + stagingRepository.setPackedIndexDir(repository.getPackedIndexDir()); + } + // in case of absolute dir do not use the same + } + stagingRepository.setRefreshCronExpression(repository.getRefreshCronExpression()); + stagingRepository.setReleases(repository.isReleases()); + stagingRepository.setRetentionCount(repository.getRetentionCount()); + stagingRepository.setScanned(repository.isScanned()); + stagingRepository.setSnapshots(repository.isSnapshots()); + stagingRepository.setSkipPackedIndexCreation(repository.isSkipPackedIndexCreation()); + // do not duplicate description + //stagingRepository.getDescription("") + return stagingRepository; + } + + private void setBaseConfig( EditableRepository repo, AbstractRepositoryConfiguration cfg) + { + + URI baseUri = archivaConfiguration.getRepositoryBaseDir().toUri(); + repo.setBaseUri(baseUri); + + repo.setName(repo.getPrimaryLocale(), cfg.getName()); + repo.setDescription(repo.getPrimaryLocale(), cfg.getDescription()); + repo.setLayout(cfg.getLayout()); + } + + public ArchivaConfiguration getArchivaConfiguration() { + return archivaConfiguration; + } + + public void setArchivaConfiguration(ArchivaConfiguration archivaConfiguration) { + this.archivaConfiguration = archivaConfiguration; + } + + @Override + public void handle(Event event) { + // + } + +} diff --git a/archiva-modules/archiva-maven/archiva-maven-repository/src/main/java/org/apache/archiva/maven/repository/MavenSystemManager.java b/archiva-modules/archiva-maven/archiva-maven-repository/src/main/java/org/apache/archiva/maven/repository/MavenSystemManager.java new file mode 100644 index 000000000..a9906cc7c --- /dev/null +++ b/archiva-modules/archiva-maven/archiva-maven-repository/src/main/java/org/apache/archiva/maven/repository/MavenSystemManager.java @@ -0,0 +1,118 @@ +package org.apache.archiva.maven.repository; + +/* + * 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.maven.repository.dependency.tree.ArchivaRepositoryConnectorFactory; +import org.apache.maven.repository.internal.DefaultArtifactDescriptorReader; +import org.apache.maven.repository.internal.DefaultVersionRangeResolver; +import org.apache.maven.repository.internal.DefaultVersionResolver; +import org.apache.maven.repository.internal.MavenRepositorySystemUtils; +import org.eclipse.aether.DefaultRepositorySystemSession; +import org.eclipse.aether.RepositorySystem; +import org.eclipse.aether.RepositorySystemSession; +import org.eclipse.aether.collection.DependencySelector; +import org.eclipse.aether.impl.ArtifactDescriptorReader; +import org.eclipse.aether.impl.DefaultServiceLocator; +import org.eclipse.aether.impl.VersionRangeResolver; +import org.eclipse.aether.impl.VersionResolver; +import org.eclipse.aether.internal.impl.SimpleLocalRepositoryManagerFactory; +import org.eclipse.aether.repository.LocalRepository; +import org.eclipse.aether.repository.LocalRepositoryManager; +import org.eclipse.aether.repository.NoLocalRepositoryManagerException; +import org.eclipse.aether.spi.connector.RepositoryConnectorFactory; +import org.eclipse.aether.util.graph.selector.AndDependencySelector; +import org.eclipse.aether.util.graph.selector.ExclusionDependencySelector; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.stereotype.Service; + +import javax.annotation.PostConstruct; + +/** + * Some static utility methods that are used by different classes. + */ +@Service("mavenSystemManager") +public class MavenSystemManager { + + static Logger log = LoggerFactory.getLogger(MavenSystemManager.class); + + private DefaultServiceLocator locator; + private RepositorySystem system; + + @PostConstruct + private synchronized void init() { + locator = newLocator(); + system = newRepositorySystem(locator); + + } + + /** + * Creates a new aether repository system session for the given directory and assigns the + * repository to this session. + * + * @param localRepoDir The repository directory + * @return The newly created session object. + */ + public static RepositorySystemSession newRepositorySystemSession(String localRepoDir) { + DefaultRepositorySystemSession session = MavenRepositorySystemUtils.newSession(); + + LocalRepository repo = new LocalRepository(localRepoDir); + + DependencySelector depFilter = new AndDependencySelector(new ExclusionDependencySelector()); + session.setDependencySelector(depFilter); + SimpleLocalRepositoryManagerFactory repFactory = new SimpleLocalRepositoryManagerFactory(); + try { + LocalRepositoryManager manager = repFactory.newInstance(session, repo); + session.setLocalRepositoryManager(manager); + } catch (NoLocalRepositoryManagerException e) { + log.error("Could not assign the repository manager to the session: {}", e.getMessage(), e); + } + + return session; + } + + public RepositorySystem getRepositorySystem() { + return system; + } + + public DefaultServiceLocator getLocator() { + return locator; + } + + /** + * Finds the + * + * @return + */ + public static RepositorySystem newRepositorySystem(DefaultServiceLocator locator) { + return locator.getService(RepositorySystem.class); + } + + public static DefaultServiceLocator newLocator() { + DefaultServiceLocator locator = MavenRepositorySystemUtils.newServiceLocator(); + + locator.addService(RepositoryConnectorFactory.class, + ArchivaRepositoryConnectorFactory.class);// FileRepositoryConnectorFactory.class ); + locator.addService(VersionResolver.class, DefaultVersionResolver.class); + locator.addService(VersionRangeResolver.class, DefaultVersionRangeResolver.class); + locator.addService(ArtifactDescriptorReader.class, DefaultArtifactDescriptorReader.class); + + return locator; + } +} diff --git a/archiva-modules/archiva-maven/archiva-maven-repository/src/main/java/org/apache/archiva/maven/repository/content/AbstractDefaultRepositoryContent.java b/archiva-modules/archiva-maven/archiva-maven-repository/src/main/java/org/apache/archiva/maven/repository/content/AbstractDefaultRepositoryContent.java new file mode 100644 index 000000000..89c08bf8a --- /dev/null +++ b/archiva-modules/archiva-maven/archiva-maven-repository/src/main/java/org/apache/archiva/maven/repository/content/AbstractDefaultRepositoryContent.java @@ -0,0 +1,364 @@ +package org.apache.archiva.maven.repository.content; + +/* + * 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.utils.VersionUtil; +import org.apache.archiva.maven.repository.metadata.storage.ArtifactMappingProvider; +import org.apache.archiva.metadata.repository.storage.RepositoryPathTranslator; +import org.apache.archiva.repository.RepositoryContent; +import org.apache.archiva.repository.content.ItemSelector; +import org.apache.archiva.repository.content.LayoutException; +import org.apache.archiva.repository.content.base.ArchivaItemSelector; +import org.apache.commons.lang3.StringUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.util.List; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +/** + * AbstractDefaultRepositoryContent - common methods for working with default (maven 2) layout. + */ +public abstract class AbstractDefaultRepositoryContent implements RepositoryContent +{ + + + protected Logger log = LoggerFactory.getLogger( getClass() ); + + public static final String MAVEN_METADATA = "maven-metadata.xml"; + + protected static final char PATH_SEPARATOR = '/'; + + protected static final char GROUP_SEPARATOR = '.'; + + protected static final char ARTIFACT_SEPARATOR = '-'; + + private static final Pattern TIMESTAMP_PATTERN = Pattern.compile( "([0-9]{8}.[0-9]{6})-([0-9]+).*" ); + private static final Pattern MAVEN_PLUGIN_PATTERN = Pattern.compile( "^(maven-.*-plugin)|(.*-maven-plugin)$" ); + + private RepositoryPathTranslator pathTranslator; + private List artifactMappingProviders; + + + AbstractDefaultRepositoryContent() { + } + + public RepositoryPathTranslator getPathTranslator( ) + { + return pathTranslator; + } + + public void setPathTranslator( RepositoryPathTranslator pathTranslator ) + { + this.pathTranslator = pathTranslator; + } + + public void setArtifactMappingProviders(List artifactMappingProviders) { + this.artifactMappingProviders = artifactMappingProviders; + } + + public ArchivaItemSelector.Builder getArtifactFromFilename( String namespace, String projectId, String projectVersion, + String artifactFileName ) + { + if ( !artifactFileName.startsWith( projectId + "-" ) ) + { + throw new IllegalArgumentException( "Not a valid artifact path in a Maven 2 repository, filename '" + artifactFileName + + "' doesn't start with artifact ID '" + projectId + "'" ); + } + + int index = projectId.length() + 1; + String version; + String idSubStrFromVersion = artifactFileName.substring( index ); + if ( idSubStrFromVersion.startsWith( projectVersion ) && !VersionUtil.isUniqueSnapshot( projectVersion ) ) + { + // non-snapshot versions, or non-timestamped snapshot versions + version = projectVersion; + } + else if ( VersionUtil.isGenericSnapshot( projectVersion ) ) + { + // timestamped snapshots + try + { + int mainVersionLength = projectVersion.length() - 8; // 8 is length of "SNAPSHOT" + if ( mainVersionLength == 0 ) + { + throw new IllegalArgumentException( + "Timestamped snapshots must contain the main version, filename was '" + artifactFileName + "'" ); + } + + Matcher m = TIMESTAMP_PATTERN.matcher( idSubStrFromVersion.substring( mainVersionLength ) ); + m.matches(); + String timestamp = m.group( 1 ); + String buildNumber = m.group( 2 ); + version = idSubStrFromVersion.substring( 0, mainVersionLength ) + timestamp + "-" + buildNumber; + } + catch ( IllegalStateException e ) + { + throw new IllegalArgumentException( "Not a valid artifact path in a Maven 2 repository, filename '" + artifactFileName + + "' doesn't contain a timestamped version matching snapshot '" + + projectVersion + "'", e); + } + } + else + { + // invalid + throw new IllegalArgumentException( + "Not a valid artifact path in a Maven 2 repository, filename '" + artifactFileName + "' doesn't contain version '" + + projectVersion + "'" ); + } + + String classifier; + String ext; + index += version.length(); + if ( index == artifactFileName.length() ) + { + // no classifier or extension + classifier = null; + ext = null; + } + else + { + char c = artifactFileName.charAt( index ); + if ( c == '-' ) + { + // classifier up until '.' + int extIndex = artifactFileName.indexOf( '.', index ); + if ( extIndex >= 0 ) + { + classifier = artifactFileName.substring( index + 1, extIndex ); + ext = artifactFileName.substring( extIndex + 1 ); + } + else + { + classifier = artifactFileName.substring( index + 1 ); + ext = null; + } + } + else if ( c == '.' ) + { + // rest is the extension + classifier = null; + ext = artifactFileName.substring( index + 1 ); + } + else + { + throw new IllegalArgumentException( "Not a valid artifact path in a Maven 2 repository, filename '" + artifactFileName + + "' expected classifier or extension but got '" + + artifactFileName.substring( index ) + "'" ); + } + } + + ArchivaItemSelector.Builder selectorBuilder = ArchivaItemSelector.builder( ) + .withNamespace( namespace ) + .withProjectId( projectId ) + .withArtifactId( projectId ) + .withVersion( projectVersion ) + .withArtifactVersion( version ) + .withClassifier( classifier ); + + + // we use our own provider here instead of directly accessing Maven's artifact handlers as it has no way + // to select the correct order to apply multiple extensions mappings to a preferred type + // TODO: this won't allow the user to decide order to apply them if there are conflicts or desired changes - + // perhaps the plugins could register missing entries in configuration, then we just use configuration + // here? + + String type = null; + for ( ArtifactMappingProvider mapping : artifactMappingProviders ) + { + type = mapping.mapClassifierAndExtensionToType( classifier, ext ); + if ( type != null ) + { + break; + } + } + + // TODO: this is cheating! We should check the POM metadata instead + if ( type == null && "jar".equals( ext ) && isArtifactIdValidMavenPlugin( projectId ) ) + { + type = "maven-plugin"; + } + + // use extension as default + if ( type == null ) + { + type = ext; + } + + // TODO: should we allow this instead? + if ( type == null ) + { + throw new IllegalArgumentException( + "Not a valid artifact path in a Maven 2 repository, filename '" + artifactFileName + "' does not have a type" ); + } + + selectorBuilder.withType( type ); + + + return selectorBuilder; + } + + public boolean isArtifactIdValidMavenPlugin( String artifactId ) + { + return MAVEN_PLUGIN_PATTERN.matcher( artifactId ).matches(); + } + + private ArchivaItemSelector getArtifactForPath( String relativePath ) + { + String[] parts = relativePath.replace( '\\', '/' ).split( "/" ); + + int len = parts.length; + if ( len < 4 ) + { + throw new IllegalArgumentException( + "Not a valid artifact path in a Maven 2 repository, not enough directories: " + relativePath ); + } + + String fileName = parts[--len]; + String baseVersion = parts[--len]; + String artifactId = parts[--len]; + StringBuilder namespaceBuilder = new StringBuilder(); + for ( int i = 0; i < len - 1; i++ ) + { + namespaceBuilder.append( parts[i] ); + namespaceBuilder.append( '.' ); + } + namespaceBuilder.append( parts[len - 1] ); + + return getArtifactFromFilename( namespaceBuilder.toString(), artifactId, baseVersion, fileName ).build(); + } + + @Override + public ItemSelector toItemSelector( String path ) throws LayoutException + { + if ( StringUtils.isBlank( path ) ) + { + throw new LayoutException( "Unable to convert blank path." ); + } + try + { + + return getArtifactForPath( path ); + } + catch ( IllegalArgumentException e ) + { + throw new LayoutException( e.getMessage(), e ); + } + + } + + @Override + public String toPath ( ItemSelector selector ) { + if (selector==null) { + throw new IllegalArgumentException( "ItemSelector must not be null." ); + } + String projectId; + // Initialize the project id if not set + if (selector.hasProjectId()) { + projectId = selector.getProjectId( ); + } else if (selector.hasArtifactId()) { + // projectId same as artifact id, if set + projectId = selector.getArtifactId( ); + } else { + // we arrive here, if projectId && artifactId not set + return pathTranslator.toPath( selector.getNamespace(), ""); + } + if ( !selector.hasArtifactId( )) { + return pathTranslator.toPath( selector.getNamespace( ), projectId ); + } + // this part only, if projectId && artifactId is set + String artifactVersion = ""; + String version = ""; + if (selector.hasVersion() && selector.hasArtifactVersion() ) { + artifactVersion = selector.getArtifactVersion(); + version = VersionUtil.getBaseVersion( selector.getVersion( ) ); + } else if (!selector.hasVersion() && selector.hasArtifactVersion()) { + // we try to retrieve the base version, if artifact version is only set + version = VersionUtil.getBaseVersion( selector.getArtifactVersion( ) ); + artifactVersion = selector.getArtifactVersion( ); + } else if (selector.hasVersion() && !selector.hasArtifactVersion()) { + artifactVersion = selector.getVersion(); + version = VersionUtil.getBaseVersion( selector.getVersion( ) ); + } + + return pathTranslator.toPath( selector.getNamespace(), projectId, version, + constructId( selector.getArtifactId(), artifactVersion, selector.getClassifier(), selector.getType() ) ); + + } + + + public String toPath( String namespace ) + { + return formatAsDirectory( namespace ); + } + + + protected String formatAsDirectory( String directory ) + { + return directory.replace( GROUP_SEPARATOR, PATH_SEPARATOR ); + } + + private String toPath( String groupId, String artifactId, String baseVersion, String version, String classifier, + String type ) + { + if ( baseVersion != null ) + { + return pathTranslator.toPath( groupId, artifactId, baseVersion, + constructId( artifactId, version, classifier, type ) ); + } + else + { + return pathTranslator.toPath( groupId, artifactId ); + } + } + + // TODO: move into the Maven Artifact facet when refactoring away the caller - the caller will need to have access + // to the facet or filename (for the original ID) + private String constructId( String artifactId, String version, String classifier, String type ) + { + String ext = null; + for ( ArtifactMappingProvider provider : artifactMappingProviders ) + { + ext = provider.mapTypeToExtension( type ); + if ( ext != null ) + { + break; + } + } + if ( ext == null ) + { + ext = type; + } + + StringBuilder id = new StringBuilder(); + if ( ( version != null ) && ( type != null ) ) + { + id.append( artifactId ).append( ARTIFACT_SEPARATOR ).append( version ); + + if ( StringUtils.isNotBlank( classifier ) ) + { + id.append( ARTIFACT_SEPARATOR ).append( classifier ); + } + + id.append( "." ).append( ext ); + } + return id.toString(); + } +} diff --git a/archiva-modules/archiva-maven/archiva-maven-repository/src/main/java/org/apache/archiva/maven/repository/content/ArtifactExtensionMapping.java b/archiva-modules/archiva-maven/archiva-maven-repository/src/main/java/org/apache/archiva/maven/repository/content/ArtifactExtensionMapping.java new file mode 100644 index 000000000..ca70ba835 --- /dev/null +++ b/archiva-modules/archiva-maven/archiva-maven-repository/src/main/java/org/apache/archiva/maven/repository/content/ArtifactExtensionMapping.java @@ -0,0 +1,77 @@ +package org.apache.archiva.maven.repository.content; + +/* + * 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.maven.repository.metadata.storage.ArtifactMappingProvider; +import org.apache.archiva.maven.repository.metadata.storage.DefaultArtifactMappingProvider; + +/** + * ArtifactExtensionMapping + * + * + */ +public class ArtifactExtensionMapping +{ + public static final String MAVEN_ONE_PLUGIN = "maven-one-plugin"; + + // TODO: now only used in Maven 1, we should be using M1 specific mappings + private static final ArtifactMappingProvider mapping = new DefaultArtifactMappingProvider(); + + public static String getExtension( String type ) + { + String ext = mapping.mapTypeToExtension( type ); + + if ( ext == null ) + { + ext = type; + } + + return ext; + } + + public static String mapExtensionAndClassifierToType( String classifier, String extension ) + { + return mapExtensionAndClassifierToType( classifier, extension, extension ); + } + + public static String mapExtensionAndClassifierToType( String classifier, String extension, + String defaultExtension ) + { + String value = mapping.mapClassifierAndExtensionToType( classifier, extension ); + if ( value == null ) + { + // TODO: Maven 1 plugin + String value1 = null; + if ( "tar.gz".equals( extension ) ) + { + value1 = "distribution-tgz"; + } + else if ( "tar.bz2".equals( extension ) ) + { + value1 = "distribution-bzip"; + } + else if ( "zip".equals( extension ) ) + { + value1 = "distribution-zip"; + } + value = value1; + } + return value != null ? value : defaultExtension; + } +} diff --git a/archiva-modules/archiva-maven/archiva-maven-repository/src/main/java/org/apache/archiva/maven/repository/content/ArtifactInfo.java b/archiva-modules/archiva-maven/archiva-maven-repository/src/main/java/org/apache/archiva/maven/repository/content/ArtifactInfo.java new file mode 100644 index 000000000..00dca84c3 --- /dev/null +++ b/archiva-modules/archiva-maven/archiva-maven-repository/src/main/java/org/apache/archiva/maven/repository/content/ArtifactInfo.java @@ -0,0 +1,42 @@ +package org.apache.archiva.maven.repository.content; + +/* + * 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.repository.content.ArtifactType; +import org.apache.archiva.repository.content.BaseArtifactTypes; +import org.apache.archiva.repository.storage.StorageAsset; + +/** + * @author Martin Stockhammer + */ // Simple object to hold artifact information +class ArtifactInfo +{ + protected String id; + protected String version; + protected String extension; + protected String remainder; + protected String type; + protected String classifier; + protected String contentType; + protected String namespace; + protected String project; + protected String projectVersion; + protected StorageAsset asset; + protected ArtifactType artifactType = BaseArtifactTypes.MAIN; +} diff --git a/archiva-modules/archiva-maven/archiva-maven-repository/src/main/java/org/apache/archiva/maven/repository/content/FilenameParser.java b/archiva-modules/archiva-maven/archiva-maven-repository/src/main/java/org/apache/archiva/maven/repository/content/FilenameParser.java new file mode 100644 index 000000000..1e6446e4d --- /dev/null +++ b/archiva-modules/archiva-maven/archiva-maven-repository/src/main/java/org/apache/archiva/maven/repository/content/FilenameParser.java @@ -0,0 +1,258 @@ +package org.apache.archiva.maven.repository.content; + +/* + * 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.utils.VersionUtil; + +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +/** + * Generic Filename Parser for use with layout routines. + * + * + */ +public class FilenameParser +{ + private String name; + + private String extension; + + private int offset; + + private static final Pattern mavenPluginPattern = Pattern.compile( "(maven-.*-plugin)|(.*-maven-plugin)" ); + + private static final Pattern extensionPattern = + Pattern.compile( "(\\.tar\\.gz$)|(\\.tar\\.bz2$)|(\\.[\\-a-z0-9]*$)", Pattern.CASE_INSENSITIVE ); + + private static final Pattern SNAPSHOT_PATTERN = Pattern.compile( "^([0-9]{8}\\.[0-9]{6}-[0-9]+)(.*)$" ); + + private static final Pattern section = Pattern.compile( "([^-]*)" ); + + private Matcher matcher; + + public FilenameParser( String filename ) + { + this.name = filename; + + Matcher mat = extensionPattern.matcher( name ); + if ( mat.find() ) + { + extension = filename.substring( mat.start() + 1 ); + name = name.substring( 0, name.length() - extension.length() - 1 ); + } + + matcher = section.matcher( name ); + + reset(); + } + + public void reset() + { + offset = 0; + } + + public String next() + { + // Past the end of the string. + if ( offset > name.length() ) + { + return null; + } + + // Return the next section. + if ( matcher.find( offset ) ) + { + // Return found section. + offset = matcher.end() + 1; + return matcher.group(); + } + + // Nothing to return. + return null; + } + + protected String expect( String expected ) + { + String value = null; + + if ( name.startsWith( expected, offset ) ) + { + value = expected; + } + else if ( VersionUtil.isGenericSnapshot( expected ) ) + { + String version = name.substring( offset ); + + // check it starts with the same version up to the snapshot part + int leadingLength = expected.length() - 9; + if ( leadingLength > 0 && version.startsWith( expected.substring( 0, leadingLength ) ) && + version.length() > leadingLength ) + { + // If we expect a non-generic snapshot - look for the timestamp + Matcher m = SNAPSHOT_PATTERN.matcher( version.substring( leadingLength + 1 ) ); + if ( m.matches() ) + { + value = version.substring( 0, leadingLength + 1 ) + m.group( 1 ); + } + } + } + + if ( value != null ) + { + // Potential hit. check for '.' or '-' at end of expected. + int seperatorOffset = offset + value.length(); + + // Test for "out of bounds" first. + if ( seperatorOffset >= name.length() ) + { + offset = name.length(); + return value; + } + + // Test for seperator char. + char seperatorChar = name.charAt( seperatorOffset ); + if ( ( seperatorChar == '-' ) || ( seperatorChar == '.' ) ) + { + offset = seperatorOffset + 1; + return value; + } + } + + return null; + } + + /** + * Get the current seperator character. + * + * @return the seperator character (either '.' or '-'), or 0 if no seperator character available. + */ + protected char seperator() + { + // Past the end of the string? + if ( offset >= name.length() ) + { + return 0; + } + + // Before the start of the string? + if ( offset <= 0 ) + { + return 0; + } + + return name.charAt( offset - 1 ); + } + + protected String getName() + { + return name; + } + + public String getExtension() + { + return extension; + } + + public String remaining() + { + if ( offset >= name.length() ) + { + return null; + } + + String end = name.substring( offset ); + offset = name.length(); + return end; + } + + public String nextNonVersion() + { + boolean done = false; + + StringBuilder ver = new StringBuilder(); + + // Any text upto the end of a special case is considered non-version. + Matcher specialMat = mavenPluginPattern.matcher( name ); + if ( specialMat.find() ) + { + ver.append( name.substring( offset, specialMat.end() ) ); + offset = specialMat.end() + 1; + } + + while ( !done ) + { + int initialOffset = offset; + String section = next(); + if ( section == null ) + { + done = true; + } + else if ( !VersionUtil.isVersion( section ) ) + { + if ( ver.length() > 0 ) + { + ver.append( '-' ); + } + ver.append( section ); + } + else + { + offset = initialOffset; + done = true; + } + } + + return ver.toString(); + } + + protected String nextVersion() + { + boolean done = false; + + StringBuilder ver = new StringBuilder(); + + while ( !done ) + { + int initialOffset = offset; + String section = next(); + if ( section == null ) + { + done = true; + } + else if ( VersionUtil.isVersion( section ) ) + { + if ( ver.length() > 0 ) + { + ver.append( '-' ); + } + ver.append( section ); + } + else + { + offset = initialOffset; + done = true; + } + } + + return ver.toString(); + } + + +} diff --git a/archiva-modules/archiva-maven/archiva-maven-repository/src/main/java/org/apache/archiva/maven/repository/content/ManagedDefaultRepositoryContent.java b/archiva-modules/archiva-maven/archiva-maven-repository/src/main/java/org/apache/archiva/maven/repository/content/ManagedDefaultRepositoryContent.java new file mode 100644 index 000000000..12f769136 --- /dev/null +++ b/archiva-modules/archiva-maven/archiva-maven-repository/src/main/java/org/apache/archiva/maven/repository/content/ManagedDefaultRepositoryContent.java @@ -0,0 +1,1610 @@ +package org.apache.archiva.maven.repository.content; + +/* + * 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.filelock.FileLockManager; +import org.apache.archiva.common.utils.FileUtils; +import org.apache.archiva.common.utils.VersionUtil; +import org.apache.archiva.configuration.FileTypes; +import org.apache.archiva.maven.metadata.MavenMetadataReader; +import org.apache.archiva.repository.EditableManagedRepository; +import org.apache.archiva.repository.ItemDeleteStatus; +import org.apache.archiva.repository.ManagedRepository; +import org.apache.archiva.repository.ManagedRepositoryContent; +import org.apache.archiva.repository.content.Artifact; +import org.apache.archiva.repository.content.BaseArtifactTypes; +import org.apache.archiva.repository.content.BaseRepositoryContentLayout; +import org.apache.archiva.repository.content.ContentAccessException; +import org.apache.archiva.repository.content.ContentItem; +import org.apache.archiva.repository.content.DataItem; +import org.apache.archiva.repository.content.ItemNotFoundException; +import org.apache.archiva.repository.content.ItemSelector; +import org.apache.archiva.repository.content.LayoutException; +import org.apache.archiva.repository.content.LayoutRuntimeException; +import org.apache.archiva.repository.content.ManagedRepositoryContentLayout; +import org.apache.archiva.repository.content.Namespace; +import org.apache.archiva.repository.content.Project; +import org.apache.archiva.repository.content.Version; +import org.apache.archiva.repository.content.base.ArchivaContentItem; +import org.apache.archiva.repository.content.base.ArchivaItemSelector; +import org.apache.archiva.repository.content.base.ArchivaNamespace; +import org.apache.archiva.repository.content.base.ArchivaProject; +import org.apache.archiva.repository.content.base.ArchivaVersion; +import org.apache.archiva.repository.content.base.builder.ArtifactOptBuilder; +import org.apache.archiva.repository.storage.RepositoryStorage; +import org.apache.archiva.repository.storage.StorageAsset; +import org.apache.archiva.repository.storage.util.StorageUtil; +import org.apache.commons.collections4.map.ReferenceMap; +import org.apache.commons.lang3.StringUtils; + +import javax.inject.Inject; +import javax.inject.Named; +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Path; +import java.util.Arrays; +import java.util.Collections; +import java.util.List; +import java.util.Objects; +import java.util.Optional; +import java.util.function.Consumer; +import java.util.function.Predicate; +import java.util.regex.Matcher; +import java.util.regex.Pattern; +import java.util.stream.Collectors; +import java.util.stream.Stream; + +/** + * ManagedDefaultRepositoryContent + */ +public class ManagedDefaultRepositoryContent + extends AbstractDefaultRepositoryContent + implements ManagedRepositoryContent, BaseRepositoryContentLayout +{ + + // attribute flag that marks version objects that point to a snapshot artifact version + public static final String SNAPSHOT_ARTIFACT_VERSION = "maven.snav"; + + private FileTypes filetypes; + + public void setFileTypes( FileTypes fileTypes ) + { + this.filetypes = fileTypes; + } + + private ManagedRepository repository; + + private FileLockManager lockManager; + + @Inject + @Named( "metadataReader#maven" ) + MavenMetadataReader metadataReader; + + @Inject + @Named( "MavenContentHelper" ) + MavenContentHelper mavenContentHelper; + + public static final String SNAPSHOT = "SNAPSHOT"; + + public static final Pattern UNIQUE_SNAPSHOT_PATTERN = Pattern.compile( "^(SNAPSHOT|[0-9]{8}\\.[0-9]{6}-[0-9]+)(.*)" ); + public static final Pattern CLASSIFIER_PATTERN = Pattern.compile( "^-([^.]+)(\\..*)" ); + public static final Pattern COMMON_EXTENSIONS = Pattern.compile( "^(jar|war|ear|dar|tar|zip|pom|xml)$" ); + + public static final Pattern TIMESTAMP_PATTERN = Pattern.compile( "^([0-9]{8})\\.([0-9]{6})$" ); + + public static final Pattern GENERIC_SNAPSHOT_PATTERN = Pattern.compile( "^(.*)-" + SNAPSHOT ); + + private static final List> LAYOUTS = Arrays.asList( BaseRepositoryContentLayout.class ); + + /** + * We are caching content items in a weak reference map. To avoid always recreating the + * the hierarchical structure. + * TODO: Better use a object cache? E.g. our spring cache implementation? + */ + private ReferenceMap itemMap = new ReferenceMap<>( ); + private ReferenceMap dataItemMap = new ReferenceMap<>( ); + + public ManagedDefaultRepositoryContent( ) + { + super( ); + } + + public ManagedDefaultRepositoryContent( ManagedRepository repository, FileTypes fileTypes, FileLockManager lockManager ) + { + super( ); + setFileTypes( fileTypes ); + this.lockManager = lockManager; + setRepository( repository ); + } + + private StorageAsset getAssetByPath( String assetPath ) + { + return getStorage( ).getAsset( assetPath ); + } + + private StorageAsset getAsset( String namespace ) + { + String namespacePath = formatAsDirectory( namespace.trim( ) ); + if ( StringUtils.isEmpty( namespacePath ) ) + { + namespacePath = ""; + } + return getAssetByPath( namespacePath ); + } + + private StorageAsset getAsset( String namespace, String project ) + { + return getAsset( namespace ).resolve( project ); + } + + private StorageAsset getAsset( String namespace, String project, String version ) + { + return getAsset( namespace, project ).resolve( version ); + } + + private StorageAsset getAsset( String namespace, String project, String version, String fileName ) + { + return getAsset( namespace, project, version ).resolve( fileName ); + } + + + /// ************* Start of new generation interface ****************** + + + @Override + public T adaptItem( Class clazz, ContentItem item ) throws LayoutException + { + try + { + if ( clazz.isAssignableFrom( Version.class ) ) + { + if ( !item.hasCharacteristic( Version.class ) ) + { + item.setCharacteristic( Version.class, createVersionFromPath( item.getAsset( ) ) ); + } + return (T) item.adapt( Version.class ); + } + else if ( clazz.isAssignableFrom( Project.class ) ) + { + if ( !item.hasCharacteristic( Project.class ) ) + { + item.setCharacteristic( Project.class, createProjectFromPath( item.getAsset( ) ) ); + } + return (T) item.adapt( Project.class ); + } + else if ( clazz.isAssignableFrom( Namespace.class ) ) + { + if ( !item.hasCharacteristic( Namespace.class ) ) + { + item.setCharacteristic( Namespace.class, createNamespaceFromPath( item.getAsset( ) ) ); + } + return (T) item.adapt( Namespace.class ); + } + else if ( clazz.isAssignableFrom( Artifact.class ) ) + { + if ( !item.hasCharacteristic( Artifact.class ) ) + { + item.setCharacteristic( Artifact.class, createArtifactFromPath( item.getAsset( ) ) ); + } + return (T) item.adapt( Artifact.class ); + } + } catch (LayoutRuntimeException e) { + throw new LayoutException( e.getMessage( ), e ); + } + throw new LayoutException( "Could not convert item to class " + clazz); + } + + + @Override + public void deleteAllItems( ItemSelector selector, Consumer consumer ) throws ContentAccessException, IllegalArgumentException + { + try ( Stream stream = newItemStream( selector, false ) ) + { + stream.forEach( item -> { + try + { + deleteItem( item ); + consumer.accept( new ItemDeleteStatus( item ) ); + } + catch ( ItemNotFoundException e ) + { + consumer.accept( new ItemDeleteStatus( item, ItemDeleteStatus.ITEM_NOT_FOUND, e ) ); + } + catch ( Exception e ) + { + consumer.accept( new ItemDeleteStatus( item, ItemDeleteStatus.DELETION_FAILED, e ) ); + } + catch ( Throwable e ) + { + consumer.accept( new ItemDeleteStatus( item, ItemDeleteStatus.UNKNOWN, e ) ); + } + } ); + } + } + + /** + * Removes the item from the filesystem. For namespaces, projects and versions it deletes + * recursively. + * For namespaces you have to be careful, because maven repositories may have sub namespaces + * parallel to projects. Which means deleting a namespaces also deletes the sub namespaces and + * not only the projects of the given namespace. Better run the delete for each project of + * a namespace. + *

+ * Artifacts are deleted as provided. No related artifacts will be deleted. + * + * @param item the item that should be removed + * @throws ItemNotFoundException if the item does not exist + * @throws ContentAccessException if some error occurred while accessing the filesystem + */ + @Override + public void deleteItem( ContentItem item ) throws ItemNotFoundException, ContentAccessException + { + final Path baseDirectory = getRepoDir( ); + final Path itemPath = item.getAsset( ).getFilePath( ); + if ( !Files.exists( itemPath ) ) + { + throw new ItemNotFoundException( "The item " + item.toString( ) + "does not exist in the repository " + getId( ) ); + } + if ( !itemPath.toAbsolutePath( ).startsWith( baseDirectory.toAbsolutePath( ) ) ) + { + log.error( "The namespace {} to delete from repository {} is not a subdirectory of the repository base.", item, getId( ) ); + log.error( "Namespace directory: {}", itemPath ); + log.error( "Repository directory: {}", baseDirectory ); + throw new ContentAccessException( "Inconsistent directories found. Could not delete namespace." ); + } + try + { + if ( Files.isDirectory( itemPath ) ) + { + FileUtils.deleteDirectory( itemPath ); + } + else + { + Files.deleteIfExists( itemPath ); + } + } + catch ( IOException e ) + { + log.error( "Could not delete item from path {}: {}", itemPath, e.getMessage( ), e ); + throw new ContentAccessException( "Error occured while deleting item " + item + ": " + e.getMessage( ), e ); + } + } + + @Override + public void copyItem( ContentItem item, ManagedRepository destinationRepository ) throws ItemNotFoundException, ContentAccessException + { + + } + + @Override + public void copyItem( ContentItem item, ManagedRepository destinationRepository, boolean updateMetadata ) throws ItemNotFoundException, ContentAccessException + { + + } + + @Override + public ContentItem getItem( ItemSelector selector ) throws ContentAccessException, IllegalArgumentException + { + if ( selector.hasVersion( ) && selector.hasArtifactId( ) ) + { + return getArtifact( selector ); + } else if ( !selector.hasVersion() && selector.hasArtifactVersion() && selector.hasArtifactId() ) { + String baseVersion = VersionUtil.getBaseVersion( selector.getArtifactVersion( ) ); + ItemSelector selector1 = ArchivaItemSelector.builder( ).withSelector( selector ) + .withVersion(baseVersion).build(); + return getArtifact( selector1 ); + } + else if ( selector.hasProjectId( ) && selector.hasVersion( ) ) + { + return getVersion( selector ); + } + else if ( selector.hasProjectId( ) ) + { + return getProject( selector ); + } + else + { + return getNamespace( selector ); + } + } + + @Override + public Namespace getNamespace( final ItemSelector namespaceSelector ) throws ContentAccessException, IllegalArgumentException + { + StorageAsset nsPath = getAsset( namespaceSelector.getNamespace() ); + try + { + return getNamespaceFromPath( nsPath ); + } + catch ( LayoutException e ) + { + throw new IllegalArgumentException( "Not a valid selector " + e.getMessage( ), e ); + } + } + + + @Override + public Project getProject( final ItemSelector selector ) throws ContentAccessException, IllegalArgumentException + { + if ( !selector.hasProjectId( ) ) + { + throw new IllegalArgumentException( "Project id must be set" ); + } + final StorageAsset path = getAsset( selector.getNamespace( ), selector.getProjectId( ) ); + try + { + return getProjectFromPath( path ); + } + catch ( LayoutException e ) + { + throw new IllegalArgumentException( "Not a valid selector " + e.getMessage( ), e ); + } + } + + + @Override + public Version getVersion( final ItemSelector selector ) throws ContentAccessException, IllegalArgumentException + { + if ( !selector.hasProjectId( ) ) + { + throw new IllegalArgumentException( "Project id must be set" ); + } + if ( !selector.hasVersion( ) ) + { + throw new IllegalArgumentException( "Version must be set" ); + } + final StorageAsset path = getAsset( selector.getNamespace( ), selector.getProjectId( ), selector.getVersion( ) ); + try + { + return getVersionFromPath( path ); + } + catch ( LayoutException e ) + { + throw new IllegalArgumentException( "Not a valid selector " + e.getMessage( ), e ); + } + } + + + public Artifact createArtifact( final StorageAsset artifactPath, final ItemSelector selector, + final String classifier ) + { + Version version = getVersion( selector ); + ArtifactOptBuilder builder = org.apache.archiva.repository.content.base.ArchivaArtifact.withAsset( artifactPath ) + .withVersion( version ) + .withId( selector.getArtifactId( ) ) + .withArtifactVersion( mavenContentHelper.getArtifactVersion( artifactPath, selector ) ) + .withClassifier( classifier ); + if ( selector.hasType( ) ) + { + builder.withType( selector.getType( ) ); + } + return builder.build( ); + } + + public Namespace getNamespaceFromArtifactPath( final StorageAsset artifactPath ) throws LayoutException + { + if (artifactPath == null) { + throw new LayoutException( "Path null is not valid for artifact" ); + } + final StorageAsset namespacePath = artifactPath.getParent( ).getParent( ).getParent( ); + return getNamespaceFromPath( namespacePath ); + } + + public Namespace getNamespaceFromPath( final StorageAsset nsPath ) throws LayoutException + { + if (nsPath == null) { + throw new LayoutException( "Path null is not valid for namespace" ); + } + + ContentItem item; + try + { + item = itemMap.computeIfAbsent( nsPath, + path -> createNamespaceFromPath( nsPath ) ); + } + catch ( LayoutRuntimeException e ) + { + throw new LayoutException( e.getMessage( ), e.getCause() ); + } + if (!item.hasCharacteristic( Namespace.class )) { + item.setCharacteristic( Namespace.class, createNamespaceFromPath( nsPath ) ); + } + return item.adapt( Namespace.class ); + } + + public Namespace createNamespaceFromPath( final StorageAsset namespacePath) throws LayoutRuntimeException + { + if (namespacePath == null) { + throw new LayoutRuntimeException( "Path null is not valid for namespace" ); + } + final String namespace = MavenContentHelper.getNamespaceFromNamespacePath( namespacePath ); + return ArchivaNamespace.withRepository( this ) + .withAsset( namespacePath ) + .withNamespace( namespace ) + .build( ); + } + + private Project getProjectFromPath( final StorageAsset path ) throws LayoutException + { + if (path == null) { + throw new LayoutException( "Path null is not valid for project" ); + } + ContentItem item; + try + { + item = itemMap.computeIfAbsent( path, this::createProjectFromPath ); + } + catch ( LayoutRuntimeException e ) + { + throw new LayoutException( e.getMessage( ), e.getCause( ) ); + } + if (!item.hasCharacteristic( Project.class )) { + item.setCharacteristic( Project.class, createProjectFromPath( path ) ); + } + return item.adapt( Project.class ); + } + + private Project createProjectFromPath( final StorageAsset projectPath ) throws LayoutRuntimeException + { + if (projectPath==null) { + throw new LayoutRuntimeException( "Path null is not valid for project" ); + } + Namespace namespace; + try + { + namespace = getNamespaceFromPath( projectPath.getParent( ) ); + } + catch ( LayoutException e ) + { + throw new LayoutRuntimeException( e.getMessage( ), e.getCause() ); + } + return ArchivaProject.withRepository( this ).withAsset( projectPath ) + .withNamespace( namespace ) + .withId( projectPath.getName( ) ).build( ); + } + + private Project getProjectFromArtifactPath( final StorageAsset artifactPath ) throws LayoutException + { + if (artifactPath == null) { + throw new LayoutException( "Path null is not valid for artifact" ); + } + final StorageAsset projectPath = artifactPath.getParent( ).getParent( ); + return getProjectFromPath( projectPath ); + } + + private Version getVersionFromArtifactPath( final StorageAsset artifactPath ) throws LayoutException + { + if (artifactPath==null) { + throw new LayoutException( "Path null is not valid for version" ); + } + final StorageAsset versionPath = artifactPath.getParent( ); + return getVersionFromPath( versionPath ); + } + + private Version getVersionFromPath( StorageAsset path ) throws LayoutException + { + if (path==null) { + throw new LayoutException( "Path null is not valid for version" ); + } + ContentItem item; + try + { + item = itemMap.computeIfAbsent( path, this::createVersionFromPath ); + } + catch ( LayoutRuntimeException e ) + { + throw new LayoutException( e.getMessage( ), e.getCause( ) ); + } + if (!item.hasCharacteristic( Version.class )) { + item.setCharacteristic( Version.class, createVersionFromPath( path ) ); + } + return item.adapt( Version.class ); + } + + private Version createVersionFromPath(StorageAsset path) throws LayoutRuntimeException + { + if (path==null) { + throw new LayoutRuntimeException( "Path null is not valid for version" ); + } + Project proj; + try + { + proj = getProjectFromPath( path.getParent( ) ); + } + catch ( LayoutException e ) + { + throw new LayoutRuntimeException( e.getMessage( ), e ); + } + return ArchivaVersion.withRepository( this ).withAsset( path ) + .withProject( proj ).withVersion(path.getName()).build(); + } + + private Optional getOptionalArtifactFromPath( final StorageAsset artifactPath) { + try + { + return Optional.of( getArtifactFromPath( artifactPath ) ); + } + catch ( LayoutException e ) + { + log.error( "Could not get artifact from path {}", artifactPath.getPath( ) ); + return Optional.empty( ); + } + } + + private Artifact getArtifactFromPath( final StorageAsset artifactPath ) throws LayoutException + { + if (artifactPath==null) { + throw new LayoutException( "Path null is not valid for artifact" ); + } + DataItem item; + try + { + item = dataItemMap.computeIfAbsent( artifactPath, this::createArtifactFromPath ); + } + catch ( LayoutRuntimeException e ) + { + throw new LayoutException( e.getMessage( ), e.getCause() ); + } + if (!item.hasCharacteristic( Artifact.class )) { + item.setCharacteristic( Artifact.class, createArtifactFromPath( artifactPath ) ); + } + return item.adapt( Artifact.class ); + } + + private Artifact createArtifactFromPath( final StorageAsset artifactPath ) throws LayoutRuntimeException + { + if (artifactPath==null) { + throw new LayoutRuntimeException( "Path null is not valid for artifact" ); + } + final Version version; + try + { + version = getVersionFromArtifactPath( artifactPath ); + } + catch ( LayoutException e ) + { + throw new LayoutRuntimeException( e.getMessage( ), e ); + } + final ArtifactInfo info = getArtifactInfoFromPath( version.getId( ), artifactPath ); + return org.apache.archiva.repository.content.base.ArchivaArtifact.withAsset( artifactPath ) + .withVersion( version ) + .withId( info.id ) + .withClassifier( info.classifier ) + .withRemainder( info.remainder ) + .withType( info.type ) + .withArtifactVersion( info.version ) + .withContentType( info.contentType ) + .withArtifactType( info.artifactType ) + .build( ); + } + + private String getContentType(StorageAsset artifactPath) { + try + { + return Files.probeContentType( artifactPath.getFilePath( ) ); + + } + catch ( IOException e ) + { + return ""; + } + } + + + private DataItem getDataItemFromPath( final StorageAsset artifactPath ) + { + final String contentType = getContentType( artifactPath ); + return dataItemMap.computeIfAbsent( artifactPath, myArtifactPath -> + org.apache.archiva.repository.content.base.ArchivaDataItem.withAsset( artifactPath ) + .withId( artifactPath.getName( ) ) + .withContentType( contentType ) + .build( ) + ); + + } + + private ContentItem getItemFromPath( final StorageAsset itemPath ) + { + if ( itemPath.isLeaf( ) ) + { + if (dataItemMap.containsKey( itemPath )) { + return dataItemMap.get( itemPath ); + } + return getDataItemFromPath( itemPath ); + } + else + { + if (itemMap.containsKey( itemPath )) { + return itemMap.get( itemPath ); + } else { + return ArchivaContentItem.withRepository( this ).withAsset( itemPath ).build(); + } + } + } + + @Override + public ManagedRepositoryContent getGenericContent( ) + { + return this; + } + + private ArtifactInfo getArtifactInfoFromPath( final String genericVersion, final StorageAsset path ) + { + final ArtifactInfo info = new ArtifactInfo( ); + info.asset = path; + info.id = path.getParent( ).getParent( ).getName( ); + final String fileName = path.getName( ); + if ( VersionUtil.isGenericSnapshot( genericVersion ) ) + { + String baseVersion = StringUtils.substringBeforeLast( genericVersion, "-" + SNAPSHOT ); + String prefix = info.id + "-" + baseVersion + "-"; + if ( fileName.startsWith( prefix ) ) + { + String versionPostfix = StringUtils.removeStart( fileName, prefix ); + Matcher matcher = UNIQUE_SNAPSHOT_PATTERN.matcher( versionPostfix ); + if ( matcher.matches( ) ) + { + info.version = baseVersion + "-" + matcher.group( 1 ); + String newPrefix = info.id + "-" + info.version; + if ( fileName.startsWith( newPrefix ) ) + { + String classPostfix = StringUtils.removeStart( fileName, newPrefix ); + Matcher cMatch = CLASSIFIER_PATTERN.matcher( classPostfix ); + if ( cMatch.matches( ) ) + { + info.classifier = cMatch.group( 1 ); + info.remainder = cMatch.group( 2 ); + } + else + { + info.classifier = ""; + info.remainder = classPostfix; + } + } + else + { + log.debug( "Artifact does not match the maven name pattern {}", path ); + info.artifactType = BaseArtifactTypes.UNKNOWN; + info.classifier = ""; + info.remainder = StringUtils.substringAfter( fileName, prefix ); + } + } + else + { + log.debug( "Artifact does not match the snapshot version pattern {}", path ); + + info.artifactType = BaseArtifactTypes.UNKNOWN; + // This is just a guess. No guarantee to the get a usable version. + info.version = StringUtils.removeStart( fileName, info.id + '-' ); + String postfix = StringUtils.substringAfterLast( info.version, "." ).toLowerCase( ); + while ( COMMON_EXTENSIONS.matcher( postfix ).matches( ) ) + { + info.version = StringUtils.substringBeforeLast( info.version, "." ); + postfix = StringUtils.substringAfterLast( info.version, "." ).toLowerCase( ); + } + info.classifier = ""; + info.remainder = StringUtils.substringAfter( fileName, prefix ); + } + } + else + { + log.debug( "Artifact does not match the maven name pattern: {}", path ); + if ( fileName.contains( "-" + baseVersion ) ) + { + info.id = StringUtils.substringBefore( fileName, "-" + baseVersion ); + } + else + { + info.id = fileName; + } + info.artifactType = BaseArtifactTypes.UNKNOWN; + info.version = ""; + info.classifier = ""; + info.remainder = StringUtils.substringAfterLast( fileName, "." ); + } + } + else + { + String prefix = info.id + "-" + genericVersion; + if ( fileName.startsWith( prefix + "-") ) + { + info.version = genericVersion; + String classPostfix = StringUtils.removeStart( fileName, prefix ); + Matcher cMatch = CLASSIFIER_PATTERN.matcher( classPostfix ); + if ( cMatch.matches( ) ) + { + info.classifier = cMatch.group( 1 ); + info.remainder = cMatch.group( 2 ); + } + else + { + info.classifier = ""; + info.remainder = classPostfix; + } + } else if (fileName.startsWith(prefix + ".")) { + info.version = genericVersion; + info.remainder = StringUtils.removeStart( fileName, prefix ); + info.classifier = ""; + } else if (fileName.startsWith(info.id+"-")) { + String postFix = StringUtils.removeStart( fileName, info.id + "-" ); + String versionPart = StringUtils.substringBefore( postFix, "." ); + if (VersionUtil.isVersion(versionPart)) { + info.version = versionPart; + info.remainder = StringUtils.removeStart( postFix, versionPart ); + info.classifier = ""; + } else { + info.version = ""; + info.classifier = ""; + int dotPos = fileName.indexOf( "." ); + info.remainder = fileName.substring( dotPos ); + } + + } + else + { + if ( fileName.contains( "-" + genericVersion ) ) + { + info.id = StringUtils.substringBefore( fileName, "-" + genericVersion ); + } + else + { + info.id = fileName; + info.version = ""; + } + log.debug( "Artifact does not match the version pattern {}", path ); + info.artifactType = BaseArtifactTypes.UNKNOWN; + info.classifier = ""; + info.remainder = StringUtils.substringAfterLast( fileName, "." ); + } + } + info.extension = StringUtils.substringAfterLast( fileName, "." ); + info.type = MavenContentHelper.getTypeFromClassifierAndExtension( info.classifier, info.extension ); + try + { + info.contentType = Files.probeContentType( path.getFilePath( ) ); + } + catch ( IOException e ) + { + info.contentType = ""; + // + } + if ( MavenContentHelper.METADATA_FILENAME.equalsIgnoreCase( fileName ) ) + { + info.artifactType = BaseArtifactTypes.METADATA; + } + else if ( MavenContentHelper.METADATA_REPOSITORY_FILENAME.equalsIgnoreCase( fileName ) ) + { + info.artifactType = MavenTypes.REPOSITORY_METADATA; + } + else if ( StringUtils.isNotEmpty( info.remainder ) && StringUtils.countMatches( info.remainder, "." ) >= 2 ) + { + String mainFile = StringUtils.substringBeforeLast( fileName, "." ); + if ( path.getParent( ).resolve( mainFile ).exists( ) ) + { + info.artifactType = BaseArtifactTypes.RELATED; + } + } + return info; + + } + + @Override + public Artifact getArtifact( final ItemSelector selectorArg ) throws ContentAccessException + { + ItemSelector selector = selectorArg; + if ( !selectorArg.hasProjectId( ) ) + { + throw new IllegalArgumentException( "Project id must be set" ); + } + if ( !selectorArg.hasVersion( ) ) + { + if (selectorArg.hasArtifactVersion() && VersionUtil.isSnapshot( selectorArg.getArtifactVersion() )) { + selector = ArchivaItemSelector.builder( ).withSelector( selectorArg ) + .withVersion( VersionUtil.getBaseVersion( selectorArg.getArtifactVersion( ) ) ).build(); + } else if (selectorArg.hasArtifactVersion()) { + selector = ArchivaItemSelector.builder( ).withSelector( selectorArg ) + .withVersion( selectorArg.getArtifactVersion( ) ).build(); + + } else + { + throw new IllegalArgumentException( "Version must be set" ); + } + } + if ( !selectorArg.hasArtifactId( ) ) + { + throw new IllegalArgumentException( "Artifact id must be set" ); + } + final StorageAsset artifactDir = getAsset( selector.getNamespace( ), selector.getProjectId( ), + selector.getVersion( ) ); + final String artifactVersion = mavenContentHelper.getArtifactVersion( artifactDir, selector ); + final String classifier = MavenContentHelper.getClassifier( selector ); + final String extension = MavenContentHelper.getArtifactExtension( selector ); + final String artifactId = StringUtils.isEmpty( selector.getArtifactId( ) ) ? selector.getProjectId( ) : selector.getArtifactId( ); + final String fileName = MavenContentHelper.getArtifactFileName( artifactId, artifactVersion, classifier, extension ); + final StorageAsset path = getAsset( selector.getNamespace( ), selector.getProjectId( ), + selector.getVersion( ), fileName ); + try + { + return getArtifactFromPath( path ); + } + catch ( LayoutException e ) + { + throw new IllegalArgumentException( "The selector is not valid " + e.getMessage( ), e ); + } + } + + @Override + public Artifact getArtifact( String path ) throws LayoutException, ContentAccessException + { + StorageAsset asset = getAssetByPath( path ); + return getArtifactFromPath( asset ); + } + + /** + * Returns all the subdirectories of the given namespace directory as project. + */ + @Override + public List getProjects( Namespace namespace ) + { + return namespace.getAsset( ).list( ).stream( ) + .filter( StorageAsset::isContainer ) + .map( a -> { + try + { + return getProjectFromPath( a ); + } + catch ( LayoutException e ) + { + log.error( "Not a valid project path " + a.getPath( ), e ); + return null; + } + } ) + .filter( Objects::nonNull ) + .collect( Collectors.toList( ) ); + } + + @Override + public List getProjects( ItemSelector selector ) throws ContentAccessException, IllegalArgumentException + { + return getProjects( getNamespace( selector ) ); + } + + /** + * Returns a version object for each directory that is a direct child of the project directory. + * + * @param project the project for which the versions should be returned + * @return the list of versions or a empty list, if not version was found + */ + @Override + public List getVersions( final Project project ) + { + StorageAsset asset = getAsset( project.getNamespace( ).getId( ), project.getId( ) ); + return asset.list( ).stream( ).filter( StorageAsset::isContainer ) + .map( a -> ArchivaVersion.withAsset( a ) + .withProject( project ) + .withVersion( a.getName( ) ).build( ) ) + .collect( Collectors.toList( ) ); + } + + /** + * Returns the versions that can be found for the given selector. + * + * @param selector the item selector. At least namespace and projectId must be set. + * @return the list of version objects or a empty list, if the selector does not match a version + * @throws ContentAccessException if the access to the underlying backend failed + * @throws IllegalArgumentException if the selector has no projectId specified + */ + @Override + public List getVersions( final ItemSelector selector ) throws ContentAccessException, IllegalArgumentException + { + if ( !selector.hasProjectId( ) ) + { + log.error( "Bad item selector for version list: {}", selector ); + throw new IllegalArgumentException( "Project id not set, while retrieving versions." ); + } + final Project project = getProject( selector ); + if ( selector.hasVersion( ) ) + { + final StorageAsset asset = getAsset( selector.getNamespace( ), selector.getProjectId( ), selector.getVersion( ) ); + return asset.list( ).stream( ).map( a -> getArtifactInfoFromPath( selector.getVersion( ), a ) ) + .filter( ai -> StringUtils.isNotEmpty( ai.version ) ) + .map( v -> { + try + { + return getVersionFromArtifactPath( v.asset ); + } + catch ( LayoutException e ) + { + log.error( "Could not get version from asset " + v.asset.getPath( ) ); + return null; + } + } ) + .filter( Objects::nonNull ) + .distinct( ) + .collect( Collectors.toList( ) ); + } + else + { + return getVersions( project ); + } + } + + public List getArtifactVersions( final ItemSelector selector ) throws ContentAccessException, IllegalArgumentException + { + if ( !selector.hasProjectId( ) ) + { + log.error( "Bad item selector for version list: {}", selector ); + throw new IllegalArgumentException( "Project id not set, while retrieving versions." ); + } + final Project project = getProject( selector ); + if ( selector.hasVersion( ) ) + { + final StorageAsset asset = getAsset( selector.getNamespace( ), selector.getProjectId( ), selector.getVersion( ) ); + return asset.list( ).stream( ).map( a -> getArtifactInfoFromPath( selector.getVersion( ), a ) ) + .filter( ai -> StringUtils.isNotEmpty( ai.version ) ) + .map( v -> v.version ) + .distinct( ) + .collect( Collectors.toList( ) ); + } + else + { + return project.getAsset( ).list( ).stream( ).map( a -> { + try + { + return getVersionFromPath( a ); + } + catch ( LayoutException e ) + { + log.error( "Could not get version from path " + a.getPath( ) ); + return null; + } + } ).filter( Objects::nonNull ) + .flatMap( v -> v.getAsset( ).list( ).stream( ).map( a -> getArtifactInfoFromPath( v.getId( ), a ) ) ) + .filter( ai -> StringUtils.isNotEmpty( ai.version ) ) + .map( v -> v.version ) + .distinct( ) + .collect( Collectors.toList( ) ); + } + } + + + /** + * See {@link #newArtifactStream(ItemSelector)}. This method collects the stream into a list. + * + * @param selector the selector for the artifacts + * @return the list of artifacts + * @throws ContentAccessException if the access to the underlying filesystem failed + */ + @Override + public List getArtifacts( ItemSelector selector ) throws ContentAccessException + { + try ( Stream stream = newArtifactStream( selector ) ) + { + return stream.collect( Collectors.toList( ) ); + } + } + + + /* + * File filter to select certain artifacts using the selector data. + */ + private Predicate getArtifactFileFilterFromSelector( final ItemSelector selector ) + { + Predicate p = StorageAsset::isLeaf; + StringBuilder fileNamePattern = new StringBuilder( "^" ); + if ( selector.hasArtifactId( ) ) + { + fileNamePattern.append( Pattern.quote( selector.getArtifactId( ) ) ).append( "-" ); + } + else + { + fileNamePattern.append( "[A-Za-z0-9_\\-.]+-" ); + } + if ( selector.hasArtifactVersion( ) ) + { + if ( selector.getArtifactVersion( ).contains( "*" ) ) + { + String[] tokens = StringUtils.splitByWholeSeparator( selector.getArtifactVersion( ), "*" ); + for ( String currentToken : tokens ) + { + if ( !currentToken.equals( "" ) ) + { + fileNamePattern.append( Pattern.quote( currentToken ) ); + } + fileNamePattern.append( "[A-Za-z0-9_\\-.]*" ); + } + } + else + { + fileNamePattern.append( Pattern.quote( selector.getArtifactVersion( ) ) ); + } + } + else + { + fileNamePattern.append( "[A-Za-z0-9_\\-.]+" ); + } + String classifier = selector.hasClassifier( ) ? selector.getClassifier( ) : + ( selector.hasType( ) ? MavenContentHelper.getClassifierFromType( selector.getType( ) ) : null ); + if ( classifier != null ) + { + if ( "*".equals( classifier ) ) + { + fileNamePattern.append( "(-[A-Za-z0-9]+)?\\." ); + } + else + { + fileNamePattern.append( "-" ).append( Pattern.quote( classifier ) ).append( "\\." ); + } + } + else + { + fileNamePattern.append( "\\." ); + } + String extension = selector.hasExtension( ) ? selector.getExtension( ) : + ( selector.hasType( ) ? MavenContentHelper.getArtifactExtension( selector ) : null ); + if ( extension != null ) + { + if ( selector.includeRelatedArtifacts( ) ) + { + fileNamePattern.append( Pattern.quote( extension ) ).append( "(\\.[A-Za-z0-9]+)?" ); + } + else + { + fileNamePattern.append( Pattern.quote( extension ) ); + } + } + else + { + fileNamePattern.append( "[A-Za-z0-9.]+" ); + } + final Pattern pattern = Pattern.compile( fileNamePattern.toString( ) ); + return p.and( a -> pattern.matcher( a.getName( ) ).matches( ) ); + } + + + /** + * Returns the artifacts. The number of artifacts returned depend on the selector. + * If the selector sets the flag {@link ItemSelector#includeRelatedArtifacts()} to true, + * additional to the matching artifacts, related artifacts like hash values or signatures are included in the artifact + * stream. + * If the selector sets the flag {@link ItemSelector#recurse()} to true, artifacts of the given + * namespace and from all sub namespaces that start with the given namespace are returned. + *

    + *
  • If only a namespace is given, all artifacts with the given namespace or starting with the given + * namespace (see {@link ItemSelector#recurse()} are returned.
  • + *
  • If a namespace and a project id, or artifact id is given, the artifacts of all versions of the given + * namespace and project are returned.
  • + *
  • If a namespace and a project id or artifact id and a version is given, the artifacts of the given + * version are returned
  • + *
  • If no artifact version or artifact id is given, it will return all "artifacts" found in the directory. + * To select only artifacts that match the layout you should add the artifact id and artifact version + * (can contain a '*' pattern).
  • + *
+ *

+ * The '*' pattern can be used in classifiers and artifact versions and match zero or more characters. + *

+ * There is no determinate order of the elements in the stream. + *

+ * Returned streams are auto closable and should be used in a try-with-resources statement. + * + * @param selector the item selector + * @throws ContentAccessException if the access to the underlying filesystem failed + */ + @Override + public Stream newArtifactStream( ItemSelector selector ) throws ContentAccessException + { + String projectId = selector.hasProjectId( ) ? selector.getProjectId( ) : ( selector.hasArtifactId( ) ? selector.getArtifactId( ) + : null ); + final Predicate filter = getArtifactFileFilterFromSelector( selector ); + if ( projectId != null && selector.hasVersion( ) ) + { + return getAsset( selector.getNamespace( ), projectId, selector.getVersion( ) ) + .list( ).stream( ).filter( filter ) + .map( this::getOptionalArtifactFromPath ) + .filter( Optional::isPresent ).map( Optional::get ); + } + else if ( projectId != null ) + { + final StorageAsset projDir = getAsset( selector.getNamespace( ), projectId ); + return projDir.list( ).stream( ) + .map( a -> a.isContainer( ) ? a.list( ) : Collections.singletonList( a ) ) + .flatMap( List::stream ) + .filter( filter ) + .map( this::getOptionalArtifactFromPath ) + .filter( Optional::isPresent ).map( Optional::get ); + } + else + { + StorageAsset namespaceDir = getAsset( selector.getNamespace( ) ); + if ( selector.recurse( ) ) + { + return StorageUtil.newAssetStream( namespaceDir, true ) + .filter( filter ) + .map( this::getOptionalArtifactFromPath ) + .filter( Optional::isPresent ).map( Optional::get ); + } + else + { + // We descend into 2 subdirectories (project and version) + return namespaceDir.list( ).stream( ) + .map( a -> a.isContainer( ) ? a.list( ) : Collections.singletonList( a ) ) + .flatMap( List::stream ) + .map( a -> a.isContainer( ) ? a.list( ) : Collections.singletonList( a ) ) + .flatMap( List::stream ) + .filter( filter ) + .map( this::getOptionalArtifactFromPath ) + .filter( Optional::isPresent ).map( Optional::get ); + } + } + } + + /** + * Same as {@link #newArtifactStream(ContentItem)} but returns the collected stream as list. + * + * @param item the item the parent item + * @return the list of artifacts or a empty list of no artifacts where found + */ + @Override + public List getArtifacts( ContentItem item ) + { + try ( Stream stream = newArtifactStream( item ) ) + { + return stream.collect( Collectors.toList( ) ); + } + } + + /** + * Returns all artifacts + * + * @param item the namespace to search for artifacts + * @return the stream of artifacts + * @throws ContentAccessException if the access to the underlying storage failed + */ + public Stream newArtifactStream( Namespace item ) throws ContentAccessException + { + return newArtifactStream( ArchivaItemSelector.builder( ).withNamespace( item.getId( ) ).build( ) ); + } + + public Stream newArtifactStream( Project item ) throws ContentAccessException + { + return newArtifactStream( ArchivaItemSelector.builder( ).withNamespace( item.getNamespace( ).getId( ) ) + .withProjectId( item.getId( ) ).build( ) ); + } + + public Stream newArtifactStream( Version item ) throws ContentAccessException + { + return newArtifactStream( ArchivaItemSelector.builder( ).withNamespace( item.getProject( ).getNamespace( ).getId( ) ) + .withProjectId( item.getProject( ).getId( ) ) + .withVersion( item.getId( ) ).build( ) ); + } + + /** + * Returns all related artifacts that match the given artifact. That means all artifacts that have + * the same filename plus an additional extension, e.g. ${fileName}.sha2 + * + * @param item the artifact + * @return the stream of artifacts + * @throws ContentAccessException if access to the underlying storage failed + */ + public Stream newArtifactStream( Artifact item ) throws ContentAccessException + { + final Version v = item.getVersion( ); + final String fileName = item.getFileName( ); + final Predicate filter = ( StorageAsset a ) -> + a.getName( ).startsWith( fileName + "." ); + return v.getAsset( ).list( ).stream( ).filter( filter ) + .map( a -> { + try + { + return getArtifactFromPath( a ); + } + catch ( LayoutException e ) + { + log.error( "Not a valid artifact path " + a.getPath( ), e ); + return null; + } + } ).filter( Objects::nonNull ); + } + + /** + * Returns the stream of artifacts that are children of the given item. + * + * @param item the item from where the artifacts should be returned + * @return the stream of artifacts + * @throws ContentAccessException if access to the underlying storage failed + */ + @Override + public Stream newArtifactStream( ContentItem item ) throws ContentAccessException + { + if ( item instanceof Namespace ) + { + return newArtifactStream( ( (Namespace) item ) ); + } + else if ( item instanceof Project ) + { + return newArtifactStream( (Project) item ); + } + else if ( item instanceof Version ) + { + return newArtifactStream( (Version) item ); + } + else if ( item instanceof Artifact ) + { + return newArtifactStream( (Artifact) item ); + } + else + { + log.warn( "newArtifactStream for unsupported item requested: {}", item.getClass( ).getName( ) ); + return Stream.empty( ); + } + } + + private void appendPatternRegex( StringBuilder builder, String name ) + { + String[] patternArray = name.split( "[*]" ); + for ( int i = 0; i < patternArray.length - 1; i++ ) + { + builder.append( Pattern.quote( patternArray[i] ) ) + .append( "[A-Za-z0-9_\\-]*" ); + } + builder.append( Pattern.quote( patternArray[patternArray.length - 1] ) ); + } + + Predicate getItemFileFilterFromSelector( ItemSelector selector ) + { + if ( !selector.hasNamespace( ) && !selector.hasProjectId( ) ) + { + throw new IllegalArgumentException( "Selector must have at least namespace and projectid" ); + } + StringBuilder pathMatcher = new StringBuilder( "^" ); + if ( selector.hasNamespace( ) ) + { + String path = "/" + String.join( "/", selector.getNamespace( ).split( "\\." ) ); + if ( path.contains( "*" ) ) + { + appendPatternRegex( pathMatcher, path ); + } + else + { + pathMatcher.append( Pattern.quote( path ) ); + } + + } + if ( selector.hasProjectId( ) ) + { + pathMatcher.append( "/" ); + if ( selector.getProjectId( ).contains( "*" ) ) + { + appendPatternRegex( pathMatcher, selector.getProjectId( ) ); + } + else + { + pathMatcher.append( Pattern.quote( selector.getProjectId( ) ) ); + } + } + if ( selector.hasVersion( ) ) + { + pathMatcher.append( "/" ); + if ( selector.getVersion( ).contains( "*" ) ) + { + appendPatternRegex( pathMatcher, selector.getVersion( ) ); + } + else + { + pathMatcher.append( Pattern.quote( selector.getVersion( ) ) ); + } + } + pathMatcher.append( ".*" ); + final Pattern pathPattern = Pattern.compile( pathMatcher.toString( ) ); + final Predicate pathPredicate = ( StorageAsset asset ) -> pathPattern.matcher( asset.getPath( ) ).matches( ); + if ( selector.hasArtifactId( ) || selector.hasArtifactVersion( ) || selector.hasClassifier( ) + || selector.hasType( ) || selector.hasExtension( ) ) + { + return getArtifactFileFilterFromSelector( selector ).and( pathPredicate ); + } + else + { + return pathPredicate; + } + } + + /** + * Returns a concatenation of the asset and its children as stream, if they exist. + * It descends level+1 levels down. + * + * @param a the asset to start from + * @param level the number of child levels to descend. 0 means only the children of the given asset, 1 means the children of childrens of the given asset, ... + * @return the stream of storage assets + */ + private Stream getChildrenDF( StorageAsset a, int level ) + { + if ( a.isContainer( ) ) + { + if (level>0) { + return Stream.concat( a.list().stream( ).flatMap( ch -> getChildrenDF( ch, level - 1 ) ), Stream.of( a ) ); + } else + { + return Stream.concat( a.list( ).stream( ), Stream.of( a ) ); + } + } + else + { + return Stream.of( a ); + } + } + + @Override + public Stream newItemStream( ItemSelector selector, boolean parallel ) throws ContentAccessException, IllegalArgumentException + { + final Predicate filter = getItemFileFilterFromSelector( selector ); + StorageAsset startDir; + if (selector.getNamespace().contains("*")) { + startDir = getAsset(""); + } else if ( selector.hasProjectId( ) && selector.getProjectId().contains("*") ) + { + startDir = getAsset( selector.getNamespace( ) ); + } else if ( selector.hasProjectId() && selector.hasVersion() && selector.getVersion().contains("*")) { + startDir = getAsset( selector.getNamespace( ), selector.getProjectId( ) ); + } + else if ( selector.hasProjectId( ) && selector.hasVersion( ) ) + { + startDir = getAsset( selector.getNamespace( ), selector.getProjectId( ), selector.getVersion() ); + } + else if ( selector.hasProjectId( ) ) + { + startDir = getAsset( selector.getNamespace( ), selector.getProjectId( ) ); + } + else + { + startDir = getAsset( selector.getNamespace( ) ); + if ( !selector.recurse( ) ) + { + // We descend into 2 subdirectories (project and version) + return startDir.list( ).stream( ) + .flatMap( a -> getChildrenDF( a, 1 ) ) + .map( this::getItemFromPath ); + } + } + return StorageUtil.newAssetStream( startDir, parallel ) + .filter( filter ) + .map( this::getItemFromPath ); + + } + + /** + * Checks, if the asset/file queried by the given selector exists. + */ + @Override + public boolean hasContent( ItemSelector selector ) + { + return getItem( selector ).getAsset( ).exists( ); + } + + @Override + public ContentItem getParent( ContentItem item ) + { + return getItemFromPath( item.getAsset( ).getParent( ) ); + } + + @Override + public List getChildren( ContentItem item ) + { + if (item.getAsset().isLeaf()) { + return Collections.emptyList( ); + } else { + return item.getAsset( ).list( ).stream( ).map( this::getItemFromPath ).collect( Collectors.toList( ) ); + } + } + + @Override + public T applyCharacteristic( Class clazz, ContentItem item ) throws LayoutException + { + if (item.getAsset().isLeaf()) { + if (clazz.isAssignableFrom( Artifact.class )) { + Artifact artifact = getArtifactFromPath( item.getAsset( ) ); + item.setCharacteristic( Artifact.class, artifact ); + return (T) artifact; + } else { + throw new LayoutException( "Could not adapt file to clazz " + clazz ); + } + } else { + if (clazz.isAssignableFrom( Version.class )) { + Version version = getVersionFromPath( item.getAsset( ) ); + item.setCharacteristic( Version.class, version ); + return (T) version; + } else if (clazz.isAssignableFrom( Project.class )) { + Project project = getProjectFromPath( item.getAsset( ) ); + item.setCharacteristic( Project.class, project ); + return (T) project; + } else if (clazz.isAssignableFrom( Namespace.class )) { + Namespace ns = getNamespaceFromPath( item.getAsset( ) ); + item.setCharacteristic( Namespace.class, ns ); + return (T) ns; + } else { + throw new LayoutException( "Cannot adapt directory to clazz " + clazz ); + } + } + } + + @Override + public T getLayout( Class clazz ) throws LayoutException + { + if (clazz.isAssignableFrom( this.getClass() )) { + return (T) this; + } else { + throw new LayoutException( "Cannot convert to layout " + clazz ); + } + } + + @Override + public boolean supportsLayout( Class clazz ) + { + return clazz.isAssignableFrom( this.getClass( ) ); + } + + @Override + public List> getSupportedLayouts( ) + { + return LAYOUTS; + } + + /** + * Moves the file to the artifact destination + */ + @Override + public void addArtifact( Path sourceFile, Artifact destination ) throws IllegalArgumentException, ContentAccessException + { + try + { + StorageAsset asset = destination.getAsset( ); + if ( !asset.exists( ) ) + { + asset.create( ); + } + asset.replaceDataFromFile( sourceFile ); + } + catch ( IOException e ) + { + log.error( "Could not push data to asset source={} destination={}. {}", sourceFile, destination.getAsset( ).getFilePath( ), e.getMessage( ) ); + throw new ContentAccessException( e.getMessage( ), e ); + } + } + + @Override + public ContentItem toItem( String path ) throws LayoutException + { + + StorageAsset asset = getRepository( ).getAsset( path ); + ContentItem item = getItemFromPath( asset ); + if (item instanceof DataItem) { + Artifact artifact = adaptItem( Artifact.class, item ); + if (asset.getParent()==null) { + throw new LayoutException( "Path too short for maven artifact "+path ); + } + String version = asset.getParent( ).getName( ); + if (asset.getParent().getParent()==null) { + throw new LayoutException( "Path too short for maven artifact " + path ); + } + String project = item.getAsset( ).getParent( ).getParent( ).getName( ); + DataItem dataItem = (DataItem) item; + if (StringUtils.isEmpty( dataItem.getExtension())) { + throw new LayoutException( "Missing type on maven artifact" ); + } + if (!project.equals(artifact.getId())) { + throw new LayoutException( "The maven artifact id "+artifact.getId() +" does not match the project id: " + project); + } + boolean versionIsGenericSnapshot = VersionUtil.isGenericSnapshot( version ); + boolean artifactVersionIsSnapshot = VersionUtil.isSnapshot( artifact.getArtifactVersion() ); + if ( versionIsGenericSnapshot && !artifactVersionIsSnapshot ) { + throw new LayoutException( "The maven artifact has no snapshot version in snapshot directory " + dataItem ); + } + if ( !versionIsGenericSnapshot && artifactVersionIsSnapshot) { + throw new LayoutException( "The maven artifact version " + artifact.getArtifactVersion() + " is a snapshot version but inside a non snapshot directory " + version ); + } + if ( !versionIsGenericSnapshot && !version.equals( artifact.getArtifactVersion() ) ) + { + throw new LayoutException( "The maven artifact version " + artifact.getArtifactVersion() + " does not match the version directory " + version ); + } + } + return item; + } + + @Override + public ContentItem toItem( StorageAsset assetPath ) throws LayoutException + { + return toItem( assetPath.getPath( ) ); + } + + /// ************* End of new generation interface ****************** + + @Override + public String toPath( ContentItem item ) { + return item.getAsset( ).getPath( ); + } + + @Override + public DataItem getMetadataItem( Version version ) { + StorageAsset metaPath = version.getAsset( ).resolve( MAVEN_METADATA ); + return getDataItemFromPath( metaPath ); + } + + @Override + public DataItem getMetadataItem( Project project ) + { + StorageAsset metaPath = project.getAsset( ).resolve( MAVEN_METADATA ); + return getDataItemFromPath( metaPath ); + } + + + @Override + public String getId( ) + { + return repository.getId( ); + } + + @Override + public ManagedRepository getRepository( ) + { + return repository; + } + + @Override + public void setRepository( final ManagedRepository repo ) + { + this.repository = repo; + if ( repo != null ) + { + if ( repository instanceof EditableManagedRepository ) + { + ( (EditableManagedRepository) repository ).setContent( this ); + } + } + } + + private Path getRepoDir( ) + { + return repository.getRoot().getFilePath( ); + } + + private RepositoryStorage getStorage( ) + { + return repository.getRoot().getStorage( ); + } + + public void setFiletypes( FileTypes filetypes ) + { + this.filetypes = filetypes; + } + + public void setMavenContentHelper( MavenContentHelper contentHelper ) + { + this.mavenContentHelper = contentHelper; + } + + + public MavenMetadataReader getMetadataReader( ) + { + return metadataReader; + } + + public void setMetadataReader( MavenMetadataReader metadataReader ) + { + this.metadataReader = metadataReader; + } +} diff --git a/archiva-modules/archiva-maven/archiva-maven-repository/src/main/java/org/apache/archiva/maven/repository/content/MavenContentHelper.java b/archiva-modules/archiva-maven/archiva-maven-repository/src/main/java/org/apache/archiva/maven/repository/content/MavenContentHelper.java new file mode 100644 index 000000000..4597feee7 --- /dev/null +++ b/archiva-modules/archiva-maven/archiva-maven-repository/src/main/java/org/apache/archiva/maven/repository/content/MavenContentHelper.java @@ -0,0 +1,290 @@ +package org.apache.archiva.maven.repository.content; + +/* + * 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.utils.VersionUtil; +import org.apache.archiva.maven.metadata.MavenMetadataReader; +import org.apache.archiva.model.ArchivaRepositoryMetadata; +import org.apache.archiva.model.SnapshotVersion; +import org.apache.archiva.repository.content.ItemSelector; +import org.apache.archiva.repository.metadata.RepositoryMetadataException; +import org.apache.archiva.repository.storage.StorageAsset; +import org.apache.commons.lang3.StringUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.stereotype.Service; + +import javax.inject.Inject; +import javax.inject.Named; +import java.util.Comparator; +import java.util.LinkedList; +import java.util.regex.Pattern; + +/** + * Helper class that contains certain maven specific methods + */ +@Service( "MavenContentHelper" ) +public class MavenContentHelper +{ + + private static final Logger log = LoggerFactory.getLogger( MavenContentHelper.class ); + public static final Pattern UNIQUE_SNAPSHOT_NUMBER_PATTERN = Pattern.compile( "^([0-9]{8}\\.[0-9]{6}-[0-9]+)(.*)" ); + + + @Inject + @Named( "metadataReader#maven" ) + MavenMetadataReader metadataReader; + + public static final String METADATA_FILENAME = "maven-metadata.xml"; + public static final String METADATA_REPOSITORY_FILENAME = "maven-metadata-repository.xml"; + + public MavenContentHelper() { + + } + + public void setMetadataReader( MavenMetadataReader metadataReader ) + { + this.metadataReader = metadataReader; + } + + /** + * Returns the namespace string for a given path in the repository + * + * @param namespacePath the path to the namespace in the directory + * @return the namespace string that matches the given path. + */ + public static String getNamespaceFromNamespacePath( final StorageAsset namespacePath) { + LinkedList names = new LinkedList<>( ); + StorageAsset current = namespacePath; + while (current.hasParent()) { + names.addFirst( current.getName() ); + current = current.getParent( ); + } + return String.join( ".", names ); + } + + /** + * Returns the artifact version for the given artifact directory and the item selector + */ + public String getArtifactVersion( StorageAsset artifactDir, ItemSelector selector) { + if (selector.hasArtifactVersion()) { + return selector.getArtifactVersion(); + } else if (selector.hasVersion()) { + if ( VersionUtil.isGenericSnapshot( selector.getVersion() ) ) { + return getLatestArtifactSnapshotVersion( artifactDir, selector.getVersion( ) ); + } else { + return selector.getVersion( ); + } + } else { + throw new IllegalArgumentException( "No version set on the selector " ); + } + } + + + /** + * + * Returns the latest snapshot version that is referenced by the metadata file. + * + * @param artifactDir the directory of the artifact + * @param snapshotVersion the generic snapshot version (must end with '-SNAPSHOT') + * @return the real version from the metadata + */ + public String getLatestArtifactSnapshotVersion( StorageAsset artifactDir, String snapshotVersion) { + final StorageAsset metadataFile = artifactDir.resolve( METADATA_FILENAME ); + StringBuilder version = new StringBuilder( ); + try + { + ArchivaRepositoryMetadata metadata = metadataReader.read( metadataFile ); + + // re-adjust to timestamp if present, otherwise retain the original -SNAPSHOT filename + SnapshotVersion metadataVersion = metadata.getSnapshotVersion( ); + if ( metadataVersion != null && StringUtils.isNotEmpty( metadataVersion.getTimestamp( ) ) ) + { + version.append( snapshotVersion, 0, snapshotVersion.length( ) - 8 ); // remove SNAPSHOT from end + version.append( metadataVersion.getTimestamp( ) ).append( "-" ).append( metadataVersion.getBuildNumber( ) ); + return version.toString( ); + } + } + catch ( RepositoryMetadataException e ) + { + // unable to parse metadata - LOGGER it, and continue with the version as the original SNAPSHOT version + log.warn( "Invalid metadata: {} - {}", metadataFile, e.getMessage( ) ); + } + final String baseVersion = StringUtils.removeEnd( snapshotVersion, "-SNAPSHOT" ); + final String prefix = metadataFile.getParent( ).getParent( ).getName( ) + "-"+baseVersion+"-"; + return artifactDir.list( ).stream( ).filter( a -> a.getName( ).startsWith( prefix ) ) + .map( a -> StringUtils.removeStart( a.getName( ), prefix ) ) + .map( n -> UNIQUE_SNAPSHOT_NUMBER_PATTERN.matcher( n ) ) + .filter( m -> m.matches( ) ) + .map( m -> baseVersion+"-"+m.group( 1 ) ) + .sorted( Comparator.reverseOrder() ).findFirst().orElse( snapshotVersion ); + } + + + /** + * Returns a artifact filename that corresponds to the given data. + * @param artifactId the selector data + * @param artifactVersion the artifactVersion + * @param classifier the artifact classifier + * @param extension the file extension + */ + static String getArtifactFileName( String artifactId, String artifactVersion, + String classifier, String extension ) + { + StringBuilder fileName = new StringBuilder( artifactId ).append( "-" ); + fileName.append( artifactVersion ); + if ( !StringUtils.isEmpty( classifier ) ) + { + fileName.append( "-" ).append( classifier ); + } + fileName.append( "." ).append( extension ); + return fileName.toString( ); + } + + /** + * Returns the classifier for a given selector. If the selector has no classifier, but + * a type set. The classifier is generated from the type. + * + * @param selector the artifact selector + * @return the classifier or empty string if no classifier was found + */ + static String getClassifier( ItemSelector selector ) + { + if ( selector.hasClassifier( ) ) + { + return selector.getClassifier( ); + } + else if ( selector.hasType( ) ) + { + return getClassifierFromType( selector.getType( ) ); + } + else + { + return ""; + } + } + + /** + * Returns a classifier for a given type. It returns only classifier for the maven default types + * that are known. + * + * @param type the type of the artifact + * @return the classifier if one was found, otherwise a empty string + */ + static String getClassifierFromType( final String type ) + { + String testType = type.trim( ).toLowerCase( ); + switch (testType.length( )) + { + case 7: + if ("javadoc".equals(testType)) { + return "javadoc"; + } + case 8: + if ("test-jar".equals(testType)) + { + return "tests"; + } + case 10: + if ("ejb-client".equals(testType)) { + return "client"; + } + case 11: + if ("java-source".equals(testType)) { + return "sources"; + } + default: + return ""; + } + + } + + /** + * Returns the type that matches the given classifier and extension + * + * @param classifierArg the classifier + * @param extensionArg the extension + * @return the type that matches the combination of classifier and extension + */ + static String getTypeFromClassifierAndExtension( String classifierArg, String extensionArg ) + { + String extension = extensionArg.toLowerCase( ).trim( ); + String classifier = classifierArg.toLowerCase( ).trim( ); + if ( StringUtils.isEmpty( extension ) ) + { + return ""; + } + else if ( StringUtils.isEmpty( classifier ) ) + { + return extension; + } + else if ( classifier.equals( "tests" ) && extension.equals( "jar" ) ) + { + return "test-jar"; + } + else if ( classifier.equals( "client" ) && extension.equals( "jar" ) ) + { + return "ejb-client"; + } + else if ( classifier.equals( "sources" ) && extension.equals( "jar" ) ) + { + return "java-source"; + } + else if ( classifier.equals( "javadoc" ) && extension.equals( "jar" ) ) + { + return "javadoc"; + } + else + { + return extension; + } + } + + /** + * If the selector defines a type and no extension, the extension can be derived from + * the type. + * + * @param selector the item selector + * @return the extension that matches the type or the default extension "jar" if the type is not known + */ + static String getArtifactExtension( ItemSelector selector ) + { + if ( selector.hasExtension( ) ) + { + return selector.getExtension( ); + } + else if ( selector.hasType( ) ) + { + final String type = selector.getType( ).trim().toLowerCase( ); + switch (type.length()) { + case 3: + if ("pom".equals(type) || "war".equals(type) || "ear".equals(type) || "rar".equals(type)) { + return type; + } + default: + return "jar"; + + } + } + else + { + return "jar"; + } + } +} diff --git a/archiva-modules/archiva-maven/archiva-maven-repository/src/main/java/org/apache/archiva/maven/repository/content/MavenContentProvider.java b/archiva-modules/archiva-maven/archiva-maven-repository/src/main/java/org/apache/archiva/maven/repository/content/MavenContentProvider.java new file mode 100644 index 000000000..eb80f7746 --- /dev/null +++ b/archiva-modules/archiva-maven/archiva-maven-repository/src/main/java/org/apache/archiva/maven/repository/content/MavenContentProvider.java @@ -0,0 +1,140 @@ +package org.apache.archiva.maven.repository.content; + +/* + * 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.filelock.FileLockManager; +import org.apache.archiva.configuration.FileTypes; +import org.apache.archiva.maven.repository.metadata.storage.ArtifactMappingProvider; +import org.apache.archiva.metadata.repository.storage.RepositoryPathTranslator; +import org.apache.archiva.repository.ManagedRepository; +import org.apache.archiva.repository.ManagedRepositoryContent; +import org.apache.archiva.repository.RemoteRepository; +import org.apache.archiva.repository.RemoteRepositoryContent; +import org.apache.archiva.repository.Repository; +import org.apache.archiva.repository.RepositoryContent; +import org.apache.archiva.repository.RepositoryContentProvider; +import org.apache.archiva.repository.RepositoryException; +import org.apache.archiva.repository.RepositoryType; +import org.apache.archiva.repository.content.BaseRepositoryContentLayout; +import org.springframework.stereotype.Service; + +import javax.inject.Inject; +import javax.inject.Named; +import java.util.HashSet; +import java.util.List; +import java.util.Set; + +/** + * Maven implementation of the repository content provider. Only default layout and + * maven repository types are supported. + */ +@Service("repositoryContentProvider#maven") +public class MavenContentProvider implements RepositoryContentProvider +{ + + @Inject + @Named( "fileTypes" ) + private FileTypes filetypes; + + @Inject + private FileLockManager fileLockManager; + + @Inject + protected List artifactMappingProviders; + + @Inject + @Named("MavenContentHelper") + MavenContentHelper mavenContentHelper; + + @Inject + @Named("repositoryPathTranslator#maven2") + RepositoryPathTranslator pathTranslator; + + private static final Set REPOSITORY_TYPES = new HashSet<>( ); + static { + REPOSITORY_TYPES.add(RepositoryType.MAVEN); + } + + @Override + public boolean supportsLayout( String layout ) + { + return "default".equals( layout ); + } + + @Override + public Set getSupportedRepositoryTypes( ) + { + return REPOSITORY_TYPES; + } + + @Override + public boolean supports( RepositoryType type ) + { + return type.equals( RepositoryType.MAVEN ); + } + + @Override + public RemoteRepositoryContent createRemoteContent( RemoteRepository repository ) throws RepositoryException + { + if (!supports( repository.getType() )) { + throw new RepositoryException( "Repository type "+repository.getType()+" is not supported by this implementation." ); + } + if (!supportsLayout( repository.getLayout() )) { + throw new RepositoryException( "Repository layout "+repository.getLayout()+" is not supported by this implementation." ); + } + RemoteDefaultRepositoryContent content = new RemoteDefaultRepositoryContent(); + content.setRepository( repository ); + content.setPathTranslator( pathTranslator ); + content.setArtifactMappingProviders( artifactMappingProviders ); + return content; + } + + @Override + public ManagedRepositoryContent createManagedContent( ManagedRepository repository ) throws RepositoryException + { + if (!supports( repository.getType() )) { + throw new RepositoryException( "Repository type "+repository.getType()+" is not supported by this implementation." ); + } + if (!supportsLayout( repository.getLayout() )) { + throw new RepositoryException( "Repository layout "+repository.getLayout()+" is not supported by this implementation." ); + } + ManagedDefaultRepositoryContent content = new ManagedDefaultRepositoryContent(repository, filetypes ,fileLockManager); + content.setMavenContentHelper( mavenContentHelper ); + content.setPathTranslator( pathTranslator ); + content.setArtifactMappingProviders( artifactMappingProviders ); + return content; + } + + @SuppressWarnings( "unchecked" ) + @Override + public T createContent( Class clazz, V repository ) throws RepositoryException + { + if (!supports( repository.getType() )) { + throw new RepositoryException( "Repository type "+repository.getType()+" is not supported by this implementation." ); + } + if (repository instanceof ManagedRepository && BaseRepositoryContentLayout.class.isAssignableFrom( clazz ) ) { + return (T) this.createManagedContent( (ManagedRepository) repository ); + } else if (repository instanceof RemoteRepository && RemoteRepository.class.isAssignableFrom( clazz )) { + return (T) this.createRemoteContent( (RemoteRepository) repository ); + } else { + throw new RepositoryException( "Repository flavour is not supported: "+repository.getClass().getName() ); + } + } + +} diff --git a/archiva-modules/archiva-maven/archiva-maven-repository/src/main/java/org/apache/archiva/maven/repository/content/MavenRepositoryRequestInfo.java b/archiva-modules/archiva-maven/archiva-maven-repository/src/main/java/org/apache/archiva/maven/repository/content/MavenRepositoryRequestInfo.java new file mode 100644 index 000000000..90c7052aa --- /dev/null +++ b/archiva-modules/archiva-maven/archiva-maven-repository/src/main/java/org/apache/archiva/maven/repository/content/MavenRepositoryRequestInfo.java @@ -0,0 +1,267 @@ +package org.apache.archiva.maven.repository.content; + +/* + * 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.repository.ManagedRepository; +import org.apache.archiva.repository.RepositoryRequestInfo; +import org.apache.archiva.repository.UnsupportedFeatureException; +import org.apache.archiva.repository.content.BaseRepositoryContentLayout; +import org.apache.archiva.repository.content.ItemSelector; +import org.apache.archiva.repository.content.LayoutException; +import org.apache.archiva.repository.features.RepositoryFeature; +import org.apache.archiva.repository.metadata.base.MetadataTools; +import org.apache.commons.lang3.StringUtils; + +/** + * RepositoryRequest is used to determine the type of request that is incoming, and convert it to an appropriate + * ArtifactReference. + */ +public class MavenRepositoryRequestInfo implements RepositoryRequestInfo +{ + ManagedRepository repository; + + public MavenRepositoryRequestInfo(ManagedRepository repository) + { + this.repository = repository; + } + + @Override + public ItemSelector toItemSelector( String requestPath ) throws LayoutException + { + return repository.getContent( ).toItemSelector( requestPath ); + } + + /** + *

+ * Tests the path to see if it conforms to the expectations of a metadata request. + *

+ *

+ * NOTE: This does a cursory check on the path's last element. A result of true + * from this method is not a guarantee that the metadata is in a valid format, or + * that it even contains data. + *

+ * + * @param requestedPath the path to test. + * @return true if the requestedPath is likely a metadata request. + */ + public boolean isMetadata( String requestedPath ) + { + return requestedPath.endsWith( "/" + MetadataTools.MAVEN_METADATA ); + } + + /** + * @param requestedPath + * @return true if the requestedPath is likely an archetype catalog request. + */ + public boolean isArchetypeCatalog( String requestedPath ) + { + return requestedPath.endsWith( "/" + MetadataTools.MAVEN_ARCHETYPE_CATALOG ); + } + + /** + *

+ * Tests the path to see if it conforms to the expectations of a support file request. + *

+ *

+ * Tests for .sha1, .md5, .asc, and .php. + *

+ *

+ * NOTE: This does a cursory check on the path's extension only. A result of true + * from this method is not a guarantee that the support resource is in a valid format, or + * that it even contains data. + *

+ * + * @param requestedPath the path to test. + * @return true if the requestedPath is likely that of a support file request. + */ + public boolean isSupportFile( String requestedPath ) + { + int idx = requestedPath.lastIndexOf( '.' ); + if ( idx <= 0 ) + { + return false; + } + + String ext = requestedPath.substring( idx ); + return ( ".sha1".equals( ext ) || ".md5".equals( ext ) || ".asc".equals( ext ) || ".pgp".equals( ext ) ); + } + + public boolean isMetadataSupportFile( String requestedPath ) + { + if ( isSupportFile( requestedPath ) ) + { + String basefilePath = StringUtils.substring( requestedPath, 0, requestedPath.lastIndexOf( '.' ) ); + if ( isMetadata( basefilePath ) ) + { + return true; + } + } + + return false; + } + + @Override + public String getLayout(String requestPath) { + if (isDefault(requestPath)) { + return "default"; + } else if (isLegacy(requestPath)) { + return "legacy"; + } else { + return "unknown"; + } + } + + /** + *

+ * Tests the path to see if it conforms to the expectations of a default layout request. + *

+ *

+ * NOTE: This does a cursory check on the count of path elements only. A result of + * true from this method is not a guarantee that the path sections are valid and + * can be resolved to an artifact reference. use {@link #toItemSelector(String)} + * if you want a more complete analysis of the validity of the path. + *

+ * + * @param requestedPath the path to test. + * @return true if the requestedPath is likely that of a default layout request. + */ + private boolean isDefault( String requestedPath ) + { + if ( StringUtils.isBlank( requestedPath ) ) + { + return false; + } + + String pathParts[] = StringUtils.splitPreserveAllTokens( requestedPath, '/' ); + if ( pathParts.length > 3 ) + { + return true; + } + else if ( pathParts.length == 3 ) + { + // check if artifact-level metadata (ex. eclipse/jdtcore/maven-metadata.xml) + if ( isMetadata( requestedPath ) ) + { + return true; + } + else + { + // check if checksum of artifact-level metadata (ex. eclipse/jdtcore/maven-metadata.xml.sha1) + int idx = requestedPath.lastIndexOf( '.' ); + if ( idx > 0 ) + { + String base = requestedPath.substring( 0, idx ); + if ( isMetadata( base ) && isSupportFile( requestedPath ) ) + { + return true; + } + } + + return false; + } + } + else + { + return false; + } + } + + /** + *

+ * Tests the path to see if it conforms to the expectations of a legacy layout request. + *

+ *

+ * NOTE: This does a cursory check on the count of path elements only. A result of + * true from this method is not a guarantee that the path sections are valid and + * can be resolved to an artifact reference. Use {@link #toItemSelector(String)} + * if you want a more complete analysis of the validity of the path. + *

+ * + * @param requestedPath the path to test. + * @return true if the requestedPath is likely that of a legacy layout request. + */ + private boolean isLegacy( String requestedPath ) + { + if ( StringUtils.isBlank( requestedPath ) ) + { + return false; + } + + String pathParts[] = StringUtils.splitPreserveAllTokens( requestedPath, '/' ); + return pathParts.length == 3; + } + + /** + * Adjust the requestedPath to conform to the native layout of the provided {@link BaseRepositoryContentLayout}. + * + * @param requestedPath the incoming requested path. + * @return the adjusted (to native) path. + * @throws LayoutException if the path cannot be parsed. + */ + public String toNativePath( String requestedPath) + throws LayoutException + { + if ( StringUtils.isBlank( requestedPath ) ) + { + throw new LayoutException( "Request Path is blank." ); + } + + String referencedResource = requestedPath; + // No checksum by default. + String supportfile = ""; + + // Figure out support file, and actual referencedResource. + if ( isSupportFile( requestedPath ) ) + { + int idx = requestedPath.lastIndexOf( '.' ); + referencedResource = requestedPath.substring( 0, idx ); + supportfile = requestedPath.substring( idx ); + } + + if ( isMetadata( referencedResource ) ) + { + /* Nothing to translate. + * Default layout is the only layout that can contain maven-metadata.xml files, and + * if the managedRepository is layout legacy, this request would never occur. + */ + if (requestedPath.startsWith( "/" )) { + return requestedPath; + } else + { + return "/"+requestedPath; + } + } + + + + // Treat as an artifact reference. + String adjustedPath = repository.getContent( ).toPath( repository.getContent( ).toItem( requestedPath ) ); + return adjustedPath + supportfile; + } + + @Override + public > RepositoryFeature getFeature(Class clazz) throws UnsupportedFeatureException { + return null; + } + + @Override + public > boolean supportsFeature(Class clazz) { + return false; + } +} diff --git a/archiva-modules/archiva-maven/archiva-maven-repository/src/main/java/org/apache/archiva/maven/repository/content/MavenTypes.java b/archiva-modules/archiva-maven/archiva-maven-repository/src/main/java/org/apache/archiva/maven/repository/content/MavenTypes.java new file mode 100644 index 000000000..340cff7f2 --- /dev/null +++ b/archiva-modules/archiva-maven/archiva-maven-repository/src/main/java/org/apache/archiva/maven/repository/content/MavenTypes.java @@ -0,0 +1,29 @@ +package org.apache.archiva.maven.repository.content; + +/* + * 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.repository.content.ArtifactType; + +/** + * @author Martin Stockhammer + */ +public enum MavenTypes implements ArtifactType +{ + REPOSITORY_METADATA +} diff --git a/archiva-modules/archiva-maven/archiva-maven-repository/src/main/java/org/apache/archiva/maven/repository/content/RemoteDefaultRepositoryContent.java b/archiva-modules/archiva-maven/archiva-maven-repository/src/main/java/org/apache/archiva/maven/repository/content/RemoteDefaultRepositoryContent.java new file mode 100644 index 000000000..6ed310dec --- /dev/null +++ b/archiva-modules/archiva-maven/archiva-maven-repository/src/main/java/org/apache/archiva/maven/repository/content/RemoteDefaultRepositoryContent.java @@ -0,0 +1,56 @@ +package org.apache.archiva.maven.repository.content; + +/* + * 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.repository.RemoteRepository; +import org.apache.archiva.repository.RemoteRepositoryContent; + +/** + * RemoteDefaultRepositoryContent + */ +public class RemoteDefaultRepositoryContent + extends AbstractDefaultRepositoryContent + implements RemoteRepositoryContent +{ + private RemoteRepository repository; + + + public RemoteDefaultRepositoryContent( ) { + super(); + } + + @Override + public String getId( ) + { + return repository.getId( ); + } + + @Override + public RemoteRepository getRepository( ) + { + return repository; + } + + @Override + public void setRepository( RemoteRepository repository ) + { + this.repository = repository; + } + +} diff --git a/archiva-modules/archiva-maven/archiva-maven-repository/src/main/java/org/apache/archiva/maven/repository/dependency/tree/ArchivaRepositoryConnectorFactory.java b/archiva-modules/archiva-maven/archiva-maven-repository/src/main/java/org/apache/archiva/maven/repository/dependency/tree/ArchivaRepositoryConnectorFactory.java new file mode 100644 index 000000000..295e78d28 --- /dev/null +++ b/archiva-modules/archiva-maven/archiva-maven-repository/src/main/java/org/apache/archiva/maven/repository/dependency/tree/ArchivaRepositoryConnectorFactory.java @@ -0,0 +1,100 @@ +package org.apache.archiva.maven.repository.dependency.tree; +/* + * 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.eclipse.aether.RepositorySystemSession; +import org.eclipse.aether.connector.basic.BasicRepositoryConnectorFactory; +import org.eclipse.aether.internal.impl.DefaultRepositoryLayoutProvider; +import org.eclipse.aether.repository.RemoteRepository; +import org.eclipse.aether.spi.connector.ArtifactDownload; +import org.eclipse.aether.spi.connector.ArtifactUpload; +import org.eclipse.aether.spi.connector.MetadataDownload; +import org.eclipse.aether.spi.connector.MetadataUpload; +import org.eclipse.aether.spi.connector.RepositoryConnector; +import org.eclipse.aether.spi.connector.RepositoryConnectorFactory; +import org.eclipse.aether.transfer.NoRepositoryConnectorException; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.util.Collection; + +/** + * + * Creates a dummy connector, if the default connectory factory fails to create one. + * + * @author Olivier Lamy + * @since 1.4-M3 + */ +public class ArchivaRepositoryConnectorFactory + implements RepositoryConnectorFactory +{ + + private BasicRepositoryConnectorFactory delegate = new BasicRepositoryConnectorFactory(); + + public ArchivaRepositoryConnectorFactory() + { + // no op but empty constructor needed by aether + delegate.setRepositoryLayoutProvider(new DefaultRepositoryLayoutProvider()); + } + + @Override + public RepositoryConnector newInstance( RepositorySystemSession session, RemoteRepository repository ) + throws NoRepositoryConnectorException + { + try + { + return delegate.newInstance( session, repository ); + } + catch ( NoRepositoryConnectorException e ) + { + + } + + return new RepositoryConnector() + { + + private Logger log = LoggerFactory.getLogger( getClass() ); + + @Override + public void get( Collection artifactDownloads, + Collection metadataDownloads ) + { + log.debug( "get" ); + } + + @Override + public void put( Collection artifactUploads, + Collection metadataUploads ) + { + log.debug( "put" ); + } + + @Override + public void close() + { + log.debug( "close" ); + } + }; + } + + @Override + public float getPriority( ) + { + return 0; + } +} diff --git a/archiva-modules/archiva-maven/archiva-maven-repository/src/main/java/org/apache/archiva/maven/repository/dependency/tree/DependencyTreeBuilder.java b/archiva-modules/archiva-maven/archiva-maven-repository/src/main/java/org/apache/archiva/maven/repository/dependency/tree/DependencyTreeBuilder.java new file mode 100644 index 000000000..8c6d02261 --- /dev/null +++ b/archiva-modules/archiva-maven/archiva-maven-repository/src/main/java/org/apache/archiva/maven/repository/dependency/tree/DependencyTreeBuilder.java @@ -0,0 +1,37 @@ +package org.apache.archiva.maven.repository.dependency.tree; +/* + * 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.maven.model.TreeEntry; +import org.eclipse.aether.graph.DependencyVisitor; + +import java.util.List; + +/** + * @author Olivier Lamy + */ +public interface DependencyTreeBuilder +{ + void buildDependencyTree( List repositoryIds, String groupId, String artifactId, String version, + DependencyVisitor dependencyVisitor ) + throws Exception; + + List buildDependencyTree( List repositoryIds, String groupId, String artifactId, String version ) + throws Exception; +} + diff --git a/archiva-modules/archiva-maven/archiva-maven-repository/src/main/java/org/apache/archiva/maven/repository/dependency/tree/DependencyTreeBuilderException.java b/archiva-modules/archiva-maven/archiva-maven-repository/src/main/java/org/apache/archiva/maven/repository/dependency/tree/DependencyTreeBuilderException.java new file mode 100644 index 000000000..632e9502d --- /dev/null +++ b/archiva-modules/archiva-maven/archiva-maven-repository/src/main/java/org/apache/archiva/maven/repository/dependency/tree/DependencyTreeBuilderException.java @@ -0,0 +1,31 @@ +package org.apache.archiva.maven.repository.dependency.tree; +/* + * 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-M3 + */ +public class DependencyTreeBuilderException + extends Exception +{ + public DependencyTreeBuilderException( String message, Throwable t ) + { + super( message, t ); + } +} diff --git a/archiva-modules/archiva-maven/archiva-maven-repository/src/main/java/org/apache/archiva/maven/repository/dependency/tree/Maven3DependencyTreeBuilder.java b/archiva-modules/archiva-maven/archiva-maven-repository/src/main/java/org/apache/archiva/maven/repository/dependency/tree/Maven3DependencyTreeBuilder.java new file mode 100644 index 000000000..715105560 --- /dev/null +++ b/archiva-modules/archiva-maven/archiva-maven-repository/src/main/java/org/apache/archiva/maven/repository/dependency/tree/Maven3DependencyTreeBuilder.java @@ -0,0 +1,302 @@ +package org.apache.archiva.maven.repository.dependency.tree; +/* + * 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.admin.model.RepositoryAdminException; +import org.apache.archiva.admin.model.beans.NetworkProxy; +import org.apache.archiva.admin.model.beans.ProxyConnector; +import org.apache.archiva.admin.model.networkproxy.NetworkProxyAdmin; +import org.apache.archiva.admin.model.proxyconnector.ProxyConnectorAdmin; +import org.apache.archiva.common.utils.VersionUtil; +import org.apache.archiva.maven.model.TreeEntry; +import org.apache.archiva.maven.metadata.MavenMetadataReader; +import org.apache.archiva.metadata.repository.storage.RepositoryPathTranslator; +import org.apache.archiva.model.ArchivaRepositoryMetadata; +import org.apache.archiva.repository.ManagedRepository; +import org.apache.archiva.repository.RemoteRepository; +import org.apache.archiva.repository.RepositoryRegistry; +import org.apache.archiva.maven.repository.MavenSystemManager; +import org.apache.archiva.repository.metadata.RepositoryMetadataException; +import org.apache.archiva.repository.metadata.base.MetadataTools; +import org.apache.archiva.repository.storage.StorageAsset; +import org.apache.commons.lang3.StringUtils; +import org.apache.commons.lang3.reflect.FieldUtils; +import org.apache.maven.artifact.Artifact; +import org.apache.maven.artifact.handler.manager.DefaultArtifactHandlerManager; +import org.apache.maven.artifact.repository.layout.ArtifactRepositoryLayout; +import org.apache.maven.artifact.repository.layout.DefaultRepositoryLayout; +import org.apache.maven.bridge.MavenRepositorySystem; +import org.eclipse.aether.RepositorySystem; +import org.eclipse.aether.RepositorySystemSession; +import org.eclipse.aether.artifact.DefaultArtifact; +import org.eclipse.aether.collection.CollectRequest; +import org.eclipse.aether.collection.CollectResult; +import org.eclipse.aether.collection.DependencyCollectionException; +import org.eclipse.aether.graph.Dependency; +import org.eclipse.aether.graph.DependencyVisitor; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.stereotype.Service; + +import javax.annotation.PostConstruct; +import javax.inject.Inject; +import javax.inject.Named; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +/** + * @author Olivier Lamy + * @since 1.4-M3 + */ +@Service("dependencyTreeBuilder#maven3") +public class Maven3DependencyTreeBuilder + implements DependencyTreeBuilder +{ + private Logger log = LoggerFactory.getLogger( Maven3DependencyTreeBuilder.class ); + + private MavenRepositorySystem mavenRepositorySystem; + + @Inject + @Named( "repositoryPathTranslator#maven2" ) + private RepositoryPathTranslator pathTranslator; + + @Inject + @Named("metadataReader#maven") + private MavenMetadataReader metadataReader; + + @Inject + private ProxyConnectorAdmin proxyConnectorAdmin; + + @Inject + private NetworkProxyAdmin networkProxyAdmin; + + @Inject + RepositoryRegistry repositoryRegistry; + + @Inject + MavenSystemManager mavenSystemManager; + + + @PostConstruct + public void initialize() + throws RuntimeException + { + try + { + mavenRepositorySystem = initMaven( ); + } + catch ( IllegalAccessException e ) + { + throw new RuntimeException( "Could not initialize maven" ); + } + } + + MavenRepositorySystem initMaven() throws IllegalAccessException + { + MavenRepositorySystem system = new MavenRepositorySystem( ); + DefaultArtifactHandlerManager afm = new DefaultArtifactHandlerManager( ); + DefaultRepositoryLayout layout = new DefaultRepositoryLayout( ); + FieldUtils.writeField( system, "artifactHandlerManager", afm, true); + Map map = new HashMap<>( ); + map.put( "defaultRepositoryLayout", layout ); + FieldUtils.writeField( system, "layouts", map, true); + return system; + } + + + + public void buildDependencyTree( List repositoryIds, String groupId, String artifactId, String version, + DependencyVisitor dependencyVisitor ) + throws DependencyTreeBuilderException + { + + Artifact projectArtifact = mavenRepositorySystem.createProjectArtifact(groupId, artifactId, version); + ManagedRepository repository = findArtifactInRepositories( repositoryIds, projectArtifact ); + + if ( repository == null ) + { + // metadata could not be resolved + log.info("Did not find repository with artifact {}/{}/{}", groupId, artifactId, version); + return; + } + + List remoteRepositories = new ArrayList<>(); + Map networkProxies = new HashMap<>(); + + try + { + // MRM-1411 + // TODO: this is a workaround for a lack of proxy capability in the resolvers - replace when it can all be + // handled there. It doesn't cache anything locally! + + Map> proxyConnectorsMap = proxyConnectorAdmin.getProxyConnectorAsMap(); + List proxyConnectors = proxyConnectorsMap.get( repository.getId() ); + if ( proxyConnectors != null ) + { + for ( ProxyConnector proxyConnector : proxyConnectors ) + { + remoteRepositories.add( + repositoryRegistry.getRemoteRepository( proxyConnector.getTargetRepoId() ) ); + + NetworkProxy networkProxyConfig = networkProxyAdmin.getNetworkProxy( proxyConnector.getProxyId() ); + + if ( networkProxyConfig != null ) + { + // key/value: remote repo ID/proxy info + networkProxies.put( proxyConnector.getTargetRepoId(), networkProxyConfig ); + } + } + } + } + catch ( RepositoryAdminException e ) + { + throw new DependencyTreeBuilderException( e.getMessage(), e ); + } + + // FIXME take care of relative path + ResolveRequest resolveRequest = new ResolveRequest(); + resolveRequest.dependencyVisitor = dependencyVisitor; + resolveRequest.localRepoDir = repository.getRoot().getFilePath().toAbsolutePath().toString(); + resolveRequest.groupId = groupId; + resolveRequest.artifactId = artifactId; + resolveRequest.version = version; + resolveRequest.remoteRepositories = remoteRepositories; + resolveRequest.networkProxies = networkProxies; + resolve( resolveRequest ); + } + + + @Override + public List buildDependencyTree( List repositoryIds, String groupId, String artifactId, + String version ) + throws DependencyTreeBuilderException + { + + List treeEntries = new ArrayList<>(); + TreeDependencyNodeVisitor treeDependencyNodeVisitor = new TreeDependencyNodeVisitor( treeEntries ); + + buildDependencyTree( repositoryIds, groupId, artifactId, version, treeDependencyNodeVisitor ); + + log.debug( "treeEntries: {}", treeEntries ); + return treeEntries; + } + + private static class ResolveRequest + { + String localRepoDir, groupId, artifactId, version; + + DependencyVisitor dependencyVisitor; + + List remoteRepositories; + + Map networkProxies; + + } + + + private void resolve( ResolveRequest resolveRequest ) + { + + RepositorySystem system = mavenSystemManager.getRepositorySystem(); + RepositorySystemSession session = MavenSystemManager.newRepositorySystemSession( resolveRequest.localRepoDir ); + + org.eclipse.aether.artifact.Artifact artifact = new DefaultArtifact( + resolveRequest.groupId + ":" + resolveRequest.artifactId + ":" + resolveRequest.version ); + + CollectRequest collectRequest = new CollectRequest(); + collectRequest.setRoot( new Dependency( artifact, "" ) ); + + // add remote repositories + for ( RemoteRepository remoteRepository : resolveRequest.remoteRepositories ) + { + org.eclipse.aether.repository.RemoteRepository repo = new org.eclipse.aether.repository.RemoteRepository.Builder( remoteRepository.getId( ), "default", remoteRepository.getLocation( ).toString() ).build( ); + collectRequest.addRepository(repo); + } + collectRequest.setRequestContext( "project" ); + + //collectRequest.addRepository( repo ); + + try + { + CollectResult collectResult = system.collectDependencies( session, collectRequest ); + collectResult.getRoot().accept( resolveRequest.dependencyVisitor ); + log.debug("Collected dependency results for resolve"); + } + catch ( DependencyCollectionException e ) + { + log.error( "Error while collecting dependencies (resolve): {}", e.getMessage(), e ); + } + + + + } + + private ManagedRepository findArtifactInRepositories( List repositoryIds, Artifact projectArtifact ) { + for ( String repoId : repositoryIds ) + { + ManagedRepository managedRepo = repositoryRegistry.getManagedRepository(repoId); + StorageAsset repoDir = managedRepo.getRoot(); + + StorageAsset file = pathTranslator.toFile( repoDir, projectArtifact.getGroupId(), projectArtifact.getArtifactId(), + projectArtifact.getBaseVersion(), + projectArtifact.getArtifactId() + "-" + projectArtifact.getVersion() + + ".pom" ); + + if ( file.exists() ) + { + return managedRepo; + } + // try with snapshot version + if ( StringUtils.endsWith( projectArtifact.getBaseVersion(), VersionUtil.SNAPSHOT ) ) + { + StorageAsset metadataFile = file.getParent().resolve( MetadataTools.MAVEN_METADATA ); + if ( metadataFile.exists() ) + { + try + { + ArchivaRepositoryMetadata archivaRepositoryMetadata = metadataReader.read( metadataFile); + int buildNumber = archivaRepositoryMetadata.getSnapshotVersion().getBuildNumber(); + String timeStamp = archivaRepositoryMetadata.getSnapshotVersion().getTimestamp(); + // rebuild file name with timestamped version and build number + String timeStampFileName = + new StringBuilder( projectArtifact.getArtifactId() ).append( '-' ).append( + StringUtils.remove( projectArtifact.getBaseVersion(), + "-" + VersionUtil.SNAPSHOT ) ).append( '-' ).append( + timeStamp ).append( '-' ).append( Integer.toString( buildNumber ) ).append( + ".pom" ).toString(); + StorageAsset timeStampFile = file.getParent().resolve( timeStampFileName ); + log.debug( "try to find timestamped snapshot version file: {}", timeStampFile); + if ( timeStampFile.exists() ) + { + return managedRepo; + } + } + catch ( RepositoryMetadataException e ) + { + log.warn( "skip fail to find timestamped snapshot pom: {}", e.getMessage() ); + } + } + } + } + return null; + } + +} diff --git a/archiva-modules/archiva-maven/archiva-maven-repository/src/main/java/org/apache/archiva/maven/repository/dependency/tree/TreeDependencyNodeVisitor.java b/archiva-modules/archiva-maven/archiva-maven-repository/src/main/java/org/apache/archiva/maven/repository/dependency/tree/TreeDependencyNodeVisitor.java new file mode 100644 index 000000000..cc5e46e80 --- /dev/null +++ b/archiva-modules/archiva-maven/archiva-maven-repository/src/main/java/org/apache/archiva/maven/repository/dependency/tree/TreeDependencyNodeVisitor.java @@ -0,0 +1,92 @@ +package org.apache.archiva.maven.repository.dependency.tree; +/* + * 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.maven.model.Artifact; +import org.apache.archiva.maven.model.TreeEntry; +import org.eclipse.aether.graph.DependencyNode; +import org.eclipse.aether.graph.DependencyVisitor; +import org.modelmapper.ModelMapper; +import org.modelmapper.convention.MatchingStrategies; + +import java.util.List; + +/** + * @author Olivier Lamy + * @since 1.4-M3 + */ +public class TreeDependencyNodeVisitor + implements DependencyVisitor +{ + + final List treeEntries; + + private TreeEntry currentEntry; + + private org.eclipse.aether.graph.DependencyNode firstDependencyNode; + + public TreeDependencyNodeVisitor( List treeEntries ) + { + this.treeEntries = treeEntries; + } + + + @Override + public boolean visitEnter( DependencyNode dependencyNode ) + { + TreeEntry entry = + new TreeEntry( getModelMapper().map( dependencyNode.getDependency().getArtifact(), Artifact.class ) ); + entry.getArtifact().setFileExtension( dependencyNode.getDependency().getArtifact().getExtension() ); + entry.getArtifact().setScope( dependencyNode.getDependency().getScope() ); + entry.setParent( currentEntry ); + currentEntry = entry; + + if ( firstDependencyNode == null ) + { + firstDependencyNode = dependencyNode; + treeEntries.add( currentEntry ); + } + else + { + currentEntry.getParent().getChilds().add( currentEntry ); + } + return true; + } + + @Override + public boolean visitLeave( DependencyNode dependencyNode ) + { + currentEntry = currentEntry.getParent(); + return true; + } + + private static class ModelMapperHolder + { + private static ModelMapper MODEL_MAPPER = new ModelMapper(); + + static + { + MODEL_MAPPER.getConfiguration().setMatchingStrategy( MatchingStrategies.STRICT ); + } + } + + protected ModelMapper getModelMapper() + { + return ModelMapperHolder.MODEL_MAPPER; + } +} diff --git a/archiva-modules/archiva-maven/archiva-maven-repository/src/main/java/org/apache/archiva/maven/repository/merge/Maven2RepositoryMerger.java b/archiva-modules/archiva-maven/archiva-maven-repository/src/main/java/org/apache/archiva/maven/repository/merge/Maven2RepositoryMerger.java new file mode 100644 index 000000000..4bb7fb9a4 --- /dev/null +++ b/archiva-modules/archiva-maven/archiva-maven-repository/src/main/java/org/apache/archiva/maven/repository/merge/Maven2RepositoryMerger.java @@ -0,0 +1,440 @@ +package org.apache.archiva.maven.repository.merge; + +/* + * 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.filelock.DefaultFileLockManager; +import org.apache.archiva.common.utils.VersionComparator; +import org.apache.archiva.common.utils.VersionUtil; +import org.apache.archiva.configuration.ArchivaConfiguration; +import org.apache.archiva.configuration.Configuration; +import org.apache.archiva.configuration.ManagedRepositoryConfiguration; +import org.apache.archiva.filter.Filter; +import org.apache.archiva.maven.metadata.MavenMetadataReader; +import org.apache.archiva.metadata.model.ArtifactMetadata; +import org.apache.archiva.metadata.repository.MetadataRepository; +import org.apache.archiva.metadata.repository.MetadataRepositoryException; +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.model.ArchivaRepositoryMetadata; +import org.apache.archiva.repository.RepositoryException; +import org.apache.archiva.repository.RepositoryType; +import org.apache.archiva.repository.metadata.RepositoryMetadataException; +import org.apache.archiva.repository.metadata.base.RepositoryMetadataWriter; +import org.apache.archiva.repository.storage.StorageAsset; +import org.apache.archiva.repository.storage.fs.FilesystemAsset; +import org.apache.archiva.repository.storage.fs.FilesystemStorage; +import org.apache.archiva.stagerepository.merge.RepositoryMerger; +import org.apache.archiva.stagerepository.merge.RepositoryMergerException; +import org.apache.commons.io.FileUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.stereotype.Service; + +import javax.inject.Inject; +import javax.inject.Named; +import java.io.BufferedWriter; +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.text.DateFormat; +import java.text.SimpleDateFormat; +import java.util.ArrayList; +import java.util.Calendar; +import java.util.Collections; +import java.util.Comparator; +import java.util.Date; +import java.util.List; +import java.util.TimeZone; +import java.util.TreeSet; + +/** + * + */ +@Service ("repositoryMerger#maven2") +public class Maven2RepositoryMerger + implements RepositoryMerger +{ + + @Inject + @Named("metadataReader#maven") + private MavenMetadataReader metadataReader; + + private static final Logger log = LoggerFactory.getLogger( Maven2RepositoryMerger.class ); + + private static final Comparator META_COMPARATOR = Comparator.comparing(ArtifactMetadata::getNamespace) + .thenComparing(ArtifactMetadata::getProject) + .thenComparing(ArtifactMetadata::getId) + .thenComparing(ArtifactMetadata::getVersion); + + /** + * + */ + private ArchivaConfiguration configuration; + + /** + * + */ + private RepositoryPathTranslator pathTranslator; + + private static final String METADATA_FILENAME = "maven-metadata.xml"; + + @Inject + private RepositorySessionFactory repositorySessionFactory; + + @Inject + public Maven2RepositoryMerger( + @Named (value = "archivaConfiguration#default") ArchivaConfiguration archivaConfiguration, + @Named (value = "repositoryPathTranslator#maven2") RepositoryPathTranslator repositoryPathTranslator ) + { + this.configuration = archivaConfiguration; + this.pathTranslator = repositoryPathTranslator; + } + + public void setConfiguration( ArchivaConfiguration configuration ) + { + this.configuration = configuration; + } + + @Override + public boolean supportsRepository( RepositoryType type ) + { + return RepositoryType.MAVEN.equals( type ); + } + + @Override + public void merge( MetadataRepository metadataRepository, String sourceRepoId, String targetRepoId ) + throws RepositoryMergerException + { + + try(RepositorySession session = repositorySessionFactory.createSession()) + { + List artifactsInSourceRepo = metadataRepository.getArtifacts(session , sourceRepoId ); + for ( ArtifactMetadata artifactMetadata : artifactsInSourceRepo ) + { + artifactMetadata.setRepositoryId( targetRepoId ); + createFolderStructure( sourceRepoId, targetRepoId, artifactMetadata ); + } + } + catch ( MetadataRepositoryException e ) + { + throw new RepositoryMergerException( e.getMessage(), e ); + } + catch ( IOException e ) + { + throw new RepositoryMergerException( e.getMessage(), e ); + } + catch ( RepositoryException e ) + { + throw new RepositoryMergerException( e.getMessage(), e ); + } + } + + // TODO when UI needs a subset to merge + @Override + public void merge( MetadataRepository metadataRepository, String sourceRepoId, String targetRepoId, + Filter filter ) + throws RepositoryMergerException + { + try(RepositorySession session = repositorySessionFactory.createSession()) + { + List sourceArtifacts = metadataRepository.getArtifacts(session , sourceRepoId ); + for ( ArtifactMetadata metadata : sourceArtifacts ) + { + if ( filter.accept( metadata ) ) + { + createFolderStructure( sourceRepoId, targetRepoId, metadata ); + } + } + } + catch ( MetadataRepositoryException e ) + { + throw new RepositoryMergerException( e.getMessage(), e ); + } + catch ( IOException e ) + { + throw new RepositoryMergerException( e.getMessage(), e ); + } + catch ( RepositoryException e ) + { + throw new RepositoryMergerException( e.getMessage(), e ); + } + } + + private void createFolderStructure( String sourceRepoId, String targetRepoId, ArtifactMetadata artifactMetadata ) + throws IOException, RepositoryException + { + Configuration config = configuration.getConfiguration(); + + ManagedRepositoryConfiguration targetRepoConfig = config.findManagedRepositoryById( targetRepoId ); + + ManagedRepositoryConfiguration sourceRepoConfig = config.findManagedRepositoryById( sourceRepoId ); + + Date lastUpdatedTimestamp = Calendar.getInstance().getTime(); + + TimeZone timezone = TimeZone.getTimeZone( "UTC" ); + + DateFormat fmt = new SimpleDateFormat( "yyyyMMdd.HHmmss" ); + + fmt.setTimeZone( timezone ); + + String timestamp = fmt.format( lastUpdatedTimestamp ); + + String targetRepoPath = targetRepoConfig.getLocation(); + + String sourceRepoPath = sourceRepoConfig.getLocation(); + + String artifactPath = pathTranslator.toPath( artifactMetadata.getNamespace(), artifactMetadata.getProject(), + artifactMetadata.getProjectVersion(), artifactMetadata.getId() ); + + Path sourceArtifactFile = Paths.get( sourceRepoPath, artifactPath ); + + Path targetArtifactFile = Paths.get( targetRepoPath, artifactPath ); + + log.debug( "artifactPath {}", artifactPath ); + + int lastIndex = artifactPath.lastIndexOf( RepositoryPathTranslator.PATH_SEPARATOR ); + + Path targetFile = Paths.get( targetRepoPath, artifactPath.substring( 0, lastIndex ) ); + + if ( !Files.exists(targetFile) ) + { + // create the folder structure when it does not exist + Files.createDirectories(targetFile); + } + // artifact copying + copyFile( sourceArtifactFile, targetArtifactFile ); + + // pom file copying + // TODO need to use path translator to get the pom file path +// String fileName = artifactMetadata.getProject() + "-" + artifactMetadata.getVersion() + ".pom"; +// +// File sourcePomFile = +// pathTranslator.toFile( new File( sourceRepoPath ), artifactMetadata.getId(), artifactMetadata.getProject(), +// artifactMetadata.getVersion(), fileName ); +// +// String relativePathToPomFile = sourcePomFile.getAbsolutePath().split( sourceRepoPath )[1]; +// File targetPomFile = new File( targetRepoPath, relativePathToPomFile ); + + //pom file copying (file path is taken with out using path translator) + + String index = artifactPath.substring( lastIndex + 1 ); + int last = index.lastIndexOf( '.' ); + Path sourcePomFile = Paths.get( sourceRepoPath, + artifactPath.substring( 0, lastIndex ) + "/" + artifactPath.substring( + lastIndex + 1 ).substring( 0, last ) + ".pom" ); + Path targetPomFile = Paths.get( targetRepoPath, + artifactPath.substring( 0, lastIndex ) + "/" + artifactPath.substring( + lastIndex + 1 ).substring( 0, last ) + ".pom" ); + + if ( !Files.exists(targetPomFile) && Files.exists(sourcePomFile) ) + { + copyFile( sourcePomFile, targetPomFile ); + } + + // explicitly update only if metadata-updater consumer is not enabled! + if ( !config.getRepositoryScanning().getKnownContentConsumers().contains( "metadata-updater" ) ) + { + + // updating version metadata files + FilesystemStorage fsStorage = new FilesystemStorage(Paths.get(sourceRepoPath), new DefaultFileLockManager()); + + StorageAsset versionMetaDataFileInSourceRepo = + pathTranslator.toFile( new FilesystemAsset(fsStorage, "", Paths.get(sourceRepoPath)), artifactMetadata.getNamespace(), + artifactMetadata.getProject(), artifactMetadata.getVersion(), + METADATA_FILENAME ); + + if ( versionMetaDataFileInSourceRepo.exists() ) + {//Pattern quote for windows path + String relativePathToVersionMetadataFile = + getRelativeAssetPath(versionMetaDataFileInSourceRepo); + Path versionMetaDataFileInTargetRepo = Paths.get( targetRepoPath, relativePathToVersionMetadataFile ); + + if ( !Files.exists(versionMetaDataFileInTargetRepo) ) + { + copyFile( versionMetaDataFileInSourceRepo.getFilePath(), versionMetaDataFileInTargetRepo ); + } + else + { + updateVersionMetadata( versionMetaDataFileInTargetRepo, artifactMetadata, lastUpdatedTimestamp ); + + } + } + + // updating project meta data file + StorageAsset projectDirectoryInSourceRepo = versionMetaDataFileInSourceRepo.getParent().getParent(); + StorageAsset projectMetadataFileInSourceRepo = projectDirectoryInSourceRepo.resolve(METADATA_FILENAME ); + + if ( projectMetadataFileInSourceRepo.exists() ) + { + String relativePathToProjectMetadataFile = + getRelativeAssetPath(projectMetadataFileInSourceRepo); + Path projectMetadataFileInTargetRepo = Paths.get( targetRepoPath, relativePathToProjectMetadataFile ); + + if ( !Files.exists(projectMetadataFileInTargetRepo) ) + { + + copyFile( projectMetadataFileInSourceRepo.getFilePath(), projectMetadataFileInTargetRepo ); + } + else + { + updateProjectMetadata( projectMetadataFileInTargetRepo, artifactMetadata, lastUpdatedTimestamp, + timestamp ); + } + } + } + + } + + private String getRelativeAssetPath(final StorageAsset asset) { + String relPath = asset.getPath(); + while(relPath.startsWith("/")) { + relPath = relPath.substring(1); + } + return relPath; + } + + private void copyFile( Path sourceFile, Path targetFile ) + throws IOException + { + + FileUtils.copyFile( sourceFile.toFile(), targetFile.toFile() ); + + } + + private void updateProjectMetadata( Path projectMetaDataFileIntargetRepo, ArtifactMetadata artifactMetadata, + Date lastUpdatedTimestamp, String timestamp ) + throws RepositoryMetadataException + { + ArrayList availableVersions = new ArrayList<>(); + String latestVersion = artifactMetadata.getProjectVersion(); + + ArchivaRepositoryMetadata projectMetadata = getMetadata( projectMetaDataFileIntargetRepo ); + + if ( Files.exists(projectMetaDataFileIntargetRepo) ) + { + availableVersions = (ArrayList) projectMetadata.getAvailableVersions(); + + Collections.sort( availableVersions, VersionComparator.getInstance() ); + + if ( !availableVersions.contains( artifactMetadata.getVersion() ) ) + { + availableVersions.add( artifactMetadata.getVersion() ); + } + + latestVersion = availableVersions.get( availableVersions.size() - 1 ); + } + else + { + availableVersions.add( artifactMetadata.getProjectVersion() ); + projectMetadata.setGroupId( artifactMetadata.getNamespace() ); + projectMetadata.setArtifactId( artifactMetadata.getProject() ); + } + + if ( projectMetadata.getGroupId() == null ) + { + projectMetadata.setGroupId( artifactMetadata.getNamespace() ); + } + + if ( projectMetadata.getArtifactId() == null ) + { + projectMetadata.setArtifactId( artifactMetadata.getProject() ); + } + + projectMetadata.setLatestVersion( latestVersion ); + projectMetadata.setAvailableVersions( availableVersions ); + projectMetadata.setLastUpdated( timestamp ); + projectMetadata.setLastUpdatedTimestamp( lastUpdatedTimestamp ); + + if ( !VersionUtil.isSnapshot( artifactMetadata.getVersion() ) ) + { + projectMetadata.setReleasedVersion( latestVersion ); + } + + try(BufferedWriter writer = Files.newBufferedWriter(projectMetaDataFileIntargetRepo)) { + RepositoryMetadataWriter.write( projectMetadata, writer ); + } catch (IOException e) { + throw new RepositoryMetadataException(e); + } + + } + + private void updateVersionMetadata( Path versionMetaDataFileInTargetRepo, ArtifactMetadata artifactMetadata, + Date lastUpdatedTimestamp ) + throws RepositoryMetadataException + { + ArchivaRepositoryMetadata versionMetadata = getMetadata( versionMetaDataFileInTargetRepo ); + if ( !Files.exists(versionMetaDataFileInTargetRepo) ) + { + versionMetadata.setGroupId( artifactMetadata.getNamespace() ); + versionMetadata.setArtifactId( artifactMetadata.getProject() ); + versionMetadata.setVersion( artifactMetadata.getProjectVersion() ); + } + + versionMetadata.setLastUpdatedTimestamp( lastUpdatedTimestamp ); + try(BufferedWriter writer = Files.newBufferedWriter(versionMetaDataFileInTargetRepo) ) { + RepositoryMetadataWriter.write( versionMetadata, writer); + } catch (IOException e) { + throw new RepositoryMetadataException(e); + } + } + + private ArchivaRepositoryMetadata getMetadata( Path metadataFile ) + throws RepositoryMetadataException + { + ArchivaRepositoryMetadata metadata = new ArchivaRepositoryMetadata(); + if ( Files.exists(metadataFile) ) + { + metadata = metadataReader.read( metadataFile ); + } + return metadata; + } + + @Override + public List getConflictingArtifacts( MetadataRepository metadataRepository, String sourceRepo, + String targetRepo ) + throws RepositoryMergerException + { + try(RepositorySession session = repositorySessionFactory.createSession()) + { + TreeSet targetArtifacts = new TreeSet<>(META_COMPARATOR); + targetArtifacts.addAll(metadataRepository.getArtifacts(session , targetRepo )); + TreeSet sourceArtifacts = new TreeSet<>(META_COMPARATOR); + sourceArtifacts.addAll(metadataRepository.getArtifacts(session , sourceRepo )); + sourceArtifacts.retainAll(targetArtifacts); + + return new ArrayList<>(sourceArtifacts); + } + catch ( MetadataRepositoryException e ) + { + throw new RepositoryMergerException( e.getMessage(), e ); + } + } + + public RepositorySessionFactory getRepositorySessionFactory( ) + { + return repositorySessionFactory; + } + + public void setRepositorySessionFactory( RepositorySessionFactory repositorySessionFactory ) + { + this.repositorySessionFactory = repositorySessionFactory; + } +} diff --git a/archiva-modules/archiva-maven/archiva-maven-repository/src/main/java/org/apache/archiva/maven/repository/metadata/storage/ArtifactMappingProvider.java b/archiva-modules/archiva-maven/archiva-maven-repository/src/main/java/org/apache/archiva/maven/repository/metadata/storage/ArtifactMappingProvider.java new file mode 100644 index 000000000..e8e998874 --- /dev/null +++ b/archiva-modules/archiva-maven/archiva-maven-repository/src/main/java/org/apache/archiva/maven/repository/metadata/storage/ArtifactMappingProvider.java @@ -0,0 +1,26 @@ +package org.apache.archiva.maven.repository.metadata.storage; + +/* + * 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. + */ + +public interface ArtifactMappingProvider +{ + String mapClassifierAndExtensionToType( String classifier, String ext ); + + String mapTypeToExtension( String type ); +} diff --git a/archiva-modules/archiva-maven/archiva-maven-repository/src/main/java/org/apache/archiva/maven/repository/metadata/storage/ArtifactMetadataVersionComparator.java b/archiva-modules/archiva-maven/archiva-maven-repository/src/main/java/org/apache/archiva/maven/repository/metadata/storage/ArtifactMetadataVersionComparator.java new file mode 100644 index 000000000..144184bcb --- /dev/null +++ b/archiva-modules/archiva-maven/archiva-maven-repository/src/main/java/org/apache/archiva/maven/repository/metadata/storage/ArtifactMetadataVersionComparator.java @@ -0,0 +1,42 @@ +package org.apache.archiva.maven.repository.metadata.storage; +/* + * 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.metadata.model.ArtifactMetadata; +import org.apache.maven.artifact.versioning.DefaultArtifactVersion; + +import java.util.Comparator; + +/** + * @author Olivier Lamy + * @since 1.4-M3 + */ +public class ArtifactMetadataVersionComparator + implements Comparator +{ + public static ArtifactMetadataVersionComparator INSTANCE = new ArtifactMetadataVersionComparator(); + + @Override + public int compare( ArtifactMetadata o1, ArtifactMetadata o2 ) + { + // sort by version (reverse), then ID + int result = + new DefaultArtifactVersion( o2.getVersion() ).compareTo( new DefaultArtifactVersion( o1.getVersion() ) ); + return result != 0 ? result : o1.getId().compareTo( o2.getId() ); + } +} diff --git a/archiva-modules/archiva-maven/archiva-maven-repository/src/main/java/org/apache/archiva/maven/repository/metadata/storage/DefaultArtifactMappingProvider.java b/archiva-modules/archiva-maven/archiva-maven-repository/src/main/java/org/apache/archiva/maven/repository/metadata/storage/DefaultArtifactMappingProvider.java new file mode 100644 index 000000000..f4b45366a --- /dev/null +++ b/archiva-modules/archiva-maven/archiva-maven-repository/src/main/java/org/apache/archiva/maven/repository/metadata/storage/DefaultArtifactMappingProvider.java @@ -0,0 +1,89 @@ +package org.apache.archiva.maven.repository.metadata.storage; + +/* + * 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.springframework.stereotype.Service; + +import java.util.HashMap; +import java.util.Map; + +/** + * + */ +@Service( "artifactMappingProvider#default" ) +public class DefaultArtifactMappingProvider + implements ArtifactMappingProvider +{ + private final Map classifierAndExtensionToTypeMap; + + private final Map typeToExtensionMap; + + public DefaultArtifactMappingProvider() + { + classifierAndExtensionToTypeMap = new HashMap<>( 4 ); + + // Maven 2.2.1 supplied types (excluding defaults where extension == type and no classifier) + classifierAndExtensionToTypeMap.put( "client:jar", "ejb-client" ); + classifierAndExtensionToTypeMap.put( "sources:jar", "java-source" ); + classifierAndExtensionToTypeMap.put( "javadoc:jar", "javadoc" ); + classifierAndExtensionToTypeMap.put( "tests:jar", "test-jar" ); + + typeToExtensionMap = new HashMap<>(); + + // Maven 2.2.1 supplied types (excluding defaults where extension == type and no classifier) + typeToExtensionMap.put( "ejb-client", "jar" ); + typeToExtensionMap.put( "ejb", "jar" ); + typeToExtensionMap.put( "java-source", "jar" ); + typeToExtensionMap.put( "javadoc", "jar" ); + typeToExtensionMap.put( "test-jar", "jar" ); + typeToExtensionMap.put( "maven-plugin", "jar" ); + + // Additional type + typeToExtensionMap.put( "maven-archetype", "jar" ); + + // TODO: move to maven 1 plugin - but note that it won't have the interface type and might need to reproduce the + // same thing + typeToExtensionMap.put( "maven-one-plugin", "jar" ); + typeToExtensionMap.put( "javadoc.jar", "jar" ); + typeToExtensionMap.put( "uberjar", "jar" ); + typeToExtensionMap.put( "distribution-tgz", "tar.gz" ); + typeToExtensionMap.put( "distribution-zip", "zip" ); + typeToExtensionMap.put( "aspect", "jar" ); + } + + @Override + public String mapClassifierAndExtensionToType( String classifier, String ext ) + { + if ( classifier == null ) + { + classifier = ""; + } + if ( ext == null ) + { + ext = ""; + } + return classifierAndExtensionToTypeMap.get( classifier + ":" + ext ); + } + + @Override + public String mapTypeToExtension( String type ) + { + return typeToExtensionMap.get( type ); + } +} diff --git a/archiva-modules/archiva-maven/archiva-maven-repository/src/main/java/org/apache/archiva/maven/repository/metadata/storage/DummyLifecycleBindingsInjector.java b/archiva-modules/archiva-maven/archiva-maven-repository/src/main/java/org/apache/archiva/maven/repository/metadata/storage/DummyLifecycleBindingsInjector.java new file mode 100644 index 000000000..4b5503c8f --- /dev/null +++ b/archiva-modules/archiva-maven/archiva-maven-repository/src/main/java/org/apache/archiva/maven/repository/metadata/storage/DummyLifecycleBindingsInjector.java @@ -0,0 +1,39 @@ +package org.apache.archiva.maven.repository.metadata.storage; + +/* + * 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.model.Model; +import org.apache.maven.model.building.ModelBuildingRequest; +import org.apache.maven.model.building.ModelProblemCollector; +import org.apache.maven.model.plugin.LifecycleBindingsInjector; + +/** + * Required as plexus-spring doesn't understand the optional = true argument added to Plexus and used here. + * + * + */ +public class DummyLifecycleBindingsInjector + implements LifecycleBindingsInjector +{ + @Override + public void injectLifecycleBindings( Model model, ModelBuildingRequest modelBuildingRequest, ModelProblemCollector modelProblemCollector ) + { + // left intentionally blank + } +} diff --git a/archiva-modules/archiva-maven/archiva-maven-repository/src/main/java/org/apache/archiva/maven/repository/metadata/storage/Maven2RepositoryPathTranslator.java b/archiva-modules/archiva-maven/archiva-maven-repository/src/main/java/org/apache/archiva/maven/repository/metadata/storage/Maven2RepositoryPathTranslator.java new file mode 100644 index 000000000..f8ba03a81 --- /dev/null +++ b/archiva-modules/archiva-maven/archiva-maven-repository/src/main/java/org/apache/archiva/maven/repository/metadata/storage/Maven2RepositoryPathTranslator.java @@ -0,0 +1,362 @@ +package org.apache.archiva.maven.repository.metadata.storage; + +/* + * 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.utils.VersionUtil; +import org.apache.archiva.maven.metadata.model.MavenArtifactFacet; +import org.apache.archiva.metadata.model.ArtifactMetadata; +import org.apache.archiva.metadata.repository.storage.RepositoryPathTranslator; +import org.apache.archiva.repository.storage.StorageAsset; +import org.apache.commons.lang3.StringUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.stereotype.Service; + +import javax.annotation.PostConstruct; +import javax.inject.Inject; +import java.util.List; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +/** + * + */ +@Service( "repositoryPathTranslator#maven2" ) +public class Maven2RepositoryPathTranslator + implements RepositoryPathTranslator +{ + + private static final Logger log = LoggerFactory.getLogger( Maven2RepositoryPathTranslator.class ); + + private static final char GROUP_SEPARATOR = '.'; + + private static final Pattern TIMESTAMP_PATTERN = Pattern.compile( "([0-9]{8}.[0-9]{6})-([0-9]+).*" ); + + + private static final Pattern MAVEN_PLUGIN_PATTERN = Pattern.compile( "^(maven-.*-plugin)|(.*-maven-plugin)$" ); + + /** + * + * see #initialize + */ + @Inject + private List artifactMappingProviders; + + public Maven2RepositoryPathTranslator() + { + // noop + } + + + public List getArtifactMappingProviders( ) + { + return artifactMappingProviders; + } + + public void setArtifactMappingProviders( List artifactMappingProviders ) + { + this.artifactMappingProviders = artifactMappingProviders; + } + + + @PostConstruct + public void initialize() + { + //artifactMappingProviders = new ArrayList( + // applicationContext.getBeansOfType( ArtifactMappingProvider.class ).values() ); + + } + + + public Maven2RepositoryPathTranslator( List artifactMappingProviders ) + { + this.artifactMappingProviders = artifactMappingProviders; + } + + @Override + public StorageAsset toFile(StorageAsset basedir, String namespace, String projectId, String projectVersion, String filename ) + { + return basedir.resolve( toPath( namespace, projectId, projectVersion, filename ) ); + } + + @Override + public StorageAsset toFile( StorageAsset basedir, String namespace, String projectId, String projectVersion ) + { + return basedir.resolve( toPath( namespace, projectId, projectVersion ) ); + } + + @Override + public String toPath( String namespace, String projectId, String projectVersion, String filename ) + { + StringBuilder path = new StringBuilder(); + + appendNamespaceToProjectVersion( path, namespace, projectId, projectVersion ); + path.append( PATH_SEPARATOR ); + path.append( filename ); + + return path.toString(); + } + + private void appendNamespaceToProjectVersion( StringBuilder path, String namespace, String projectId, + String projectVersion ) + { + appendNamespaceAndProject( path, namespace, projectId ); + path.append( projectVersion ); + } + + public String toPath( String namespace, String projectId, String projectVersion ) + { + StringBuilder path = new StringBuilder(); + + appendNamespaceToProjectVersion( path, namespace, projectId, projectVersion ); + + return path.toString(); + } + + public String toPath( String namespace ) + { + StringBuilder path = new StringBuilder(); + + appendNamespace( path, namespace ); + + return path.toString(); + } + + @Override + public String toPath( String namespace, String projectId ) + { + StringBuilder path = new StringBuilder(); + + appendNamespaceAndProject( path, namespace, projectId ); + + return path.toString(); + } + + private void appendNamespaceAndProject( StringBuilder path, String namespace, String projectId ) + { + appendNamespace( path, namespace ); + if (StringUtils.isNotEmpty( projectId )) + { + path.append( projectId ).append( PATH_SEPARATOR ); + } + } + + private void appendNamespace( StringBuilder path, String namespace ) + { + if ( StringUtils.isNotEmpty( namespace ) ) { + path.append( formatAsDirectory( namespace ) ).append( PATH_SEPARATOR ); + } + } + + @Override + public StorageAsset toFile( StorageAsset basedir, String namespace, String projectId ) + { + return basedir.resolve( toPath( namespace, projectId ) ); + } + + @Override + public StorageAsset toFile( StorageAsset basedir, String namespace ) + { + return basedir.resolve( toPath( namespace ) ); + } + + private String formatAsDirectory( String directory ) + { + return directory.replace( GROUP_SEPARATOR, PATH_SEPARATOR ); + } + + @Override + public ArtifactMetadata getArtifactForPath( String repoId, String relativePath ) + { + String[] parts = relativePath.replace( '\\', '/' ).split( "/" ); + + int len = parts.length; + if ( len < 4 ) + { + throw new IllegalArgumentException( + "Not a valid artifact path in a Maven 2 repository, not enough directories: " + relativePath ); + } + + String id = parts[--len]; + String baseVersion = parts[--len]; + String artifactId = parts[--len]; + StringBuilder groupIdBuilder = new StringBuilder(); + for ( int i = 0; i < len - 1; i++ ) + { + groupIdBuilder.append( parts[i] ); + groupIdBuilder.append( '.' ); + } + groupIdBuilder.append( parts[len - 1] ); + + return getArtifactFromId( repoId, groupIdBuilder.toString(), artifactId, baseVersion, id ); + } + + @Override + public ArtifactMetadata getArtifactFromId( String repoId, String namespace, String projectId, String projectVersion, + String id ) + { + if ( !id.startsWith( projectId + "-" ) ) + { + throw new IllegalArgumentException( "Not a valid artifact path in a Maven 2 repository, filename '" + id + + "' doesn't start with artifact ID '" + projectId + "'" ); + } + + MavenArtifactFacet facet = new MavenArtifactFacet(); + + int index = projectId.length() + 1; + String version; + String idSubStrFromVersion = id.substring( index ); + if ( idSubStrFromVersion.startsWith( projectVersion ) && !VersionUtil.isUniqueSnapshot( projectVersion ) ) + { + // non-snapshot versions, or non-timestamped snapshot versions + version = projectVersion; + } + else if ( VersionUtil.isGenericSnapshot( projectVersion ) ) + { + // timestamped snapshots + try + { + int mainVersionLength = projectVersion.length() - 8; // 8 is length of "SNAPSHOT" + if ( mainVersionLength == 0 ) + { + throw new IllegalArgumentException( + "Timestamped snapshots must contain the main version, filename was '" + id + "'" ); + } + + Matcher m = TIMESTAMP_PATTERN.matcher( idSubStrFromVersion.substring( mainVersionLength ) ); + m.matches(); + String timestamp = m.group( 1 ); + String buildNumber = m.group( 2 ); + facet.setTimestamp( timestamp ); + facet.setBuildNumber( Integer.parseInt( buildNumber ) ); + version = idSubStrFromVersion.substring( 0, mainVersionLength ) + timestamp + "-" + buildNumber; + } + catch ( IllegalStateException e ) + { + throw new IllegalArgumentException( "Not a valid artifact path in a Maven 2 repository, filename '" + id + + "' doesn't contain a timestamped version matching snapshot '" + + projectVersion + "'", e); + } + } + else + { + // invalid + throw new IllegalArgumentException( + "Not a valid artifact path in a Maven 2 repository, filename '" + id + "' doesn't contain version '" + + projectVersion + "'" ); + } + + String classifier; + String ext; + index += version.length(); + if ( index == id.length() ) + { + // no classifier or extension + classifier = null; + ext = null; + } + else + { + char c = id.charAt( index ); + if ( c == '-' ) + { + // classifier up until '.' + int extIndex = id.indexOf( '.', index ); + if ( extIndex >= 0 ) + { + classifier = id.substring( index + 1, extIndex ); + ext = id.substring( extIndex + 1 ); + } + else + { + classifier = id.substring( index + 1 ); + ext = null; + } + } + else if ( c == '.' ) + { + // rest is the extension + classifier = null; + ext = id.substring( index + 1 ); + } + else + { + throw new IllegalArgumentException( "Not a valid artifact path in a Maven 2 repository, filename '" + id + + "' expected classifier or extension but got '" + + id.substring( index ) + "'" ); + } + } + + ArtifactMetadata metadata = new ArtifactMetadata(); + metadata.setId( id ); + metadata.setNamespace( namespace ); + metadata.setProject( projectId ); + metadata.setRepositoryId( repoId ); + metadata.setProjectVersion( projectVersion ); + metadata.setVersion( version ); + + facet.setClassifier( classifier ); + + // we use our own provider here instead of directly accessing Maven's artifact handlers as it has no way + // to select the correct order to apply multiple extensions mappings to a preferred type + // TODO: this won't allow the user to decide order to apply them if there are conflicts or desired changes - + // perhaps the plugins could register missing entries in configuration, then we just use configuration + // here? + + String type = null; + for ( ArtifactMappingProvider mapping : artifactMappingProviders ) + { + type = mapping.mapClassifierAndExtensionToType( classifier, ext ); + if ( type != null ) + { + break; + } + } + + // TODO: this is cheating! We should check the POM metadata instead + if ( type == null && "jar".equals( ext ) && isArtifactIdValidMavenPlugin( projectId ) ) + { + type = "maven-plugin"; + } + + // use extension as default + if ( type == null ) + { + type = ext; + } + + // TODO: should we allow this instead? + if ( type == null ) + { + throw new IllegalArgumentException( + "Not a valid artifact path in a Maven 2 repository, filename '" + id + "' does not have a type" ); + } + + facet.setType( type ); + metadata.addFacet( facet ); + + return metadata; + } + + + public boolean isArtifactIdValidMavenPlugin( String artifactId ) + { + return MAVEN_PLUGIN_PATTERN.matcher( artifactId ).matches(); + } +} diff --git a/archiva-modules/archiva-maven/archiva-maven-repository/src/main/java/org/apache/archiva/maven/repository/metadata/storage/Maven2RepositoryStorage.java b/archiva-modules/archiva-maven/archiva-maven-repository/src/main/java/org/apache/archiva/maven/repository/metadata/storage/Maven2RepositoryStorage.java new file mode 100644 index 000000000..79d0fb984 --- /dev/null +++ b/archiva-modules/archiva-maven/archiva-maven-repository/src/main/java/org/apache/archiva/maven/repository/metadata/storage/Maven2RepositoryStorage.java @@ -0,0 +1,994 @@ +package org.apache.archiva.maven.repository.metadata.storage; + +/* + * 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.checksum.ChecksumAlgorithm; +import org.apache.archiva.checksum.ChecksummedFile; +import org.apache.archiva.common.Try; +import org.apache.archiva.common.utils.VersionUtil; +import org.apache.archiva.filter.Filter; +import org.apache.archiva.maven.metadata.MavenMetadataReader; +import org.apache.archiva.metadata.model.ArtifactMetadata; +import org.apache.archiva.metadata.model.ProjectMetadata; +import org.apache.archiva.metadata.model.ProjectVersionMetadata; +import org.apache.archiva.metadata.model.facets.RepositoryProblemFacet; +import org.apache.archiva.metadata.repository.storage.ReadMetadataRequest; +import org.apache.archiva.metadata.repository.storage.RelocationException; +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.metadata.repository.storage.RepositoryStorageRuntimeException; +import org.apache.archiva.model.ArchivaRepositoryMetadata; +import org.apache.archiva.model.SnapshotVersion; +import org.apache.archiva.policies.ProxyDownloadException; +import org.apache.archiva.proxy.ProxyRegistry; +import org.apache.archiva.maven.common.proxy.WagonFactory; +import org.apache.archiva.proxy.model.NetworkProxy; +import org.apache.archiva.proxy.model.ProxyConnector; +import org.apache.archiva.proxy.model.RepositoryProxyHandler; +import org.apache.archiva.repository.ManagedRepository; +import org.apache.archiva.repository.ManagedRepositoryContent; +import org.apache.archiva.repository.ReleaseScheme; +import org.apache.archiva.repository.RemoteRepository; +import org.apache.archiva.repository.RepositoryRegistry; +import org.apache.archiva.repository.RepositoryType; +import org.apache.archiva.repository.content.Artifact; +import org.apache.archiva.repository.content.BaseRepositoryContentLayout; +import org.apache.archiva.repository.content.ContentItem; +import org.apache.archiva.repository.content.ItemSelector; +import org.apache.archiva.repository.content.LayoutException; +import org.apache.archiva.repository.content.base.ArchivaItemSelector; +import org.apache.archiva.maven.repository.MavenSystemManager; +import org.apache.archiva.repository.metadata.RepositoryMetadataException; +import org.apache.archiva.repository.storage.StorageAsset; +import org.apache.commons.lang3.ArrayUtils; +import org.apache.commons.lang3.StringUtils; +import org.apache.maven.model.CiManagement; +import org.apache.maven.model.Dependency; +import org.apache.maven.model.DistributionManagement; +import org.apache.maven.model.IssueManagement; +import org.apache.maven.model.License; +import org.apache.maven.model.MailingList; +import org.apache.maven.model.Model; +import org.apache.maven.model.Organization; +import org.apache.maven.model.Relocation; +import org.apache.maven.model.Scm; +import org.apache.maven.model.building.DefaultModelBuilderFactory; +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.model.io.xpp3.MavenXpp3Reader; +import org.codehaus.plexus.util.xml.pull.XmlPullParserException; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.context.ApplicationContext; +import org.springframework.stereotype.Service; + +import javax.annotation.PostConstruct; +import javax.inject.Inject; +import javax.inject.Named; +import java.io.FileNotFoundException; +import java.io.IOException; +import java.io.Reader; +import java.nio.channels.Channels; +import java.nio.charset.Charset; +import java.nio.file.NoSuchFileException; +import java.time.ZoneId; +import java.time.ZonedDateTime; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; +import java.util.Collections; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.function.Predicate; +import java.util.stream.Collectors; + +// import java.io.FileNotFoundException; + +/** + *

+ * Maven 2 repository format storage implementation. This class currently takes parameters to indicate the repository to + * deal with rather than being instantiated per-repository. + * FIXME: instantiate one per repository and allocate permanently from a factory (which can be obtained within the session). + *

+ *

+ * The session is passed in as an argument to obtain any necessary resources, rather than the class being instantiated + * within the session in the context of a single managed repository's resolution needs. + *

+ */ +@Service("repositoryStorage#maven2") +public class Maven2RepositoryStorage + implements RepositoryStorage { + + private static final Logger log = LoggerFactory.getLogger(Maven2RepositoryStorage.class); + + private ModelBuilder builder; + + @Inject + RepositoryRegistry repositoryRegistry; + + @Inject + @Named( "metadataReader#maven" ) + MavenMetadataReader metadataReader; + + @Inject + @Named("repositoryPathTranslator#maven2") + private RepositoryPathTranslator pathTranslator; + + @Inject + private WagonFactory wagonFactory; + + @Inject + private ApplicationContext applicationContext; + + @Inject + private ProxyRegistry proxyRegistry; + + @Inject + private MavenSystemManager mavenSystemManager; + + private static final String METADATA_FILENAME_START = "maven-metadata"; + + private static final String METADATA_FILENAME = METADATA_FILENAME_START + ".xml"; + + // This array must be lexically sorted + private static final String[] IGNORED_FILES = {METADATA_FILENAME, "resolver-status.properties"}; + + private static final MavenXpp3Reader MAVEN_XPP_3_READER = new MavenXpp3Reader(); + + + @PostConstruct + public void initialize() { + builder = new DefaultModelBuilderFactory().newInstance(); + + } + + @Override + public ProjectMetadata readProjectMetadata(String repoId, String namespace, String projectId) { + // TODO: could natively implement the "shared model" concept from the browse action to avoid needing it there? + return null; + } + + @Override + public ProjectVersionMetadata readProjectVersionMetadata(ReadMetadataRequest readMetadataRequest) + throws RepositoryStorageMetadataNotFoundException, RepositoryStorageMetadataInvalidException, + RepositoryStorageRuntimeException { + + ManagedRepository managedRepository = repositoryRegistry.getManagedRepository(readMetadataRequest.getRepositoryId()); + boolean isReleases = managedRepository.getActiveReleaseSchemes().contains(ReleaseScheme.RELEASE); + boolean isSnapshots = managedRepository.getActiveReleaseSchemes().contains(ReleaseScheme.SNAPSHOT); + String artifactVersion = readMetadataRequest.getProjectVersion(); + // olamy: in case of browsing via the ui we can mix repos (parent of a SNAPSHOT can come from release repo) + if (!readMetadataRequest.isBrowsingRequest()) { + if (VersionUtil.isSnapshot(artifactVersion)) { + // skygo trying to improve speed by honoring managed configuration MRM-1658 + if (isReleases && !isSnapshots) { + throw new RepositoryStorageRuntimeException("lookforsnaponreleaseonly", + "managed repo is configured for release only"); + } + } else { + if (!isReleases && isSnapshots) { + throw new RepositoryStorageRuntimeException("lookforsreleaseonsneponly", + "managed repo is configured for snapshot only"); + } + } + } + StorageAsset basedir = managedRepository.getRoot(); + if (VersionUtil.isSnapshot(artifactVersion)) { + StorageAsset metadataFile = pathTranslator.toFile(basedir, readMetadataRequest.getNamespace(), + readMetadataRequest.getProjectId(), artifactVersion, + METADATA_FILENAME); + try { + ArchivaRepositoryMetadata metadata = metadataReader.read(metadataFile); + + // re-adjust to timestamp if present, otherwise retain the original -SNAPSHOT filename + SnapshotVersion snapshotVersion = metadata.getSnapshotVersion(); + if (snapshotVersion != null) { + artifactVersion = + artifactVersion.substring(0, artifactVersion.length() - 8); // remove SNAPSHOT from end + artifactVersion = + artifactVersion + snapshotVersion.getTimestamp() + "-" + snapshotVersion.getBuildNumber(); + } + } catch ( RepositoryMetadataException e) { + // unable to parse metadata - LOGGER it, and continue with the version as the original SNAPSHOT version + log.warn("Invalid metadata: {} - {}", metadataFile, e.getMessage()); + } + } + + // TODO: won't work well with some other layouts, might need to convert artifact parts to ID by path translator + String id = readMetadataRequest.getProjectId() + "-" + artifactVersion + ".pom"; + StorageAsset file = + pathTranslator.toFile(basedir, readMetadataRequest.getNamespace(), readMetadataRequest.getProjectId(), + readMetadataRequest.getProjectVersion(), id); + + if (!file.exists()) { + // metadata could not be resolved + throw new RepositoryStorageMetadataNotFoundException( + "The artifact's POM file '" + file.getPath() + "' was missing"); + } + + // TODO: this is a workaround until we can properly resolve using proxies as well - this doesn't cache + // anything locally! + List remoteRepositories = new ArrayList<>(); + Map networkProxies = new HashMap<>(); + + Map> proxyConnectorsMap = proxyRegistry.getProxyConnectorAsMap(); + List proxyConnectors = proxyConnectorsMap.get(readMetadataRequest.getRepositoryId()); + if (proxyConnectors != null) { + for (ProxyConnector proxyConnector : proxyConnectors) { + RemoteRepository remoteRepoConfig = + repositoryRegistry.getRemoteRepository(proxyConnector.getTargetRepository().getId()); + + if (remoteRepoConfig != null) { + remoteRepositories.add(remoteRepoConfig); + + NetworkProxy networkProxyConfig = + proxyRegistry.getNetworkProxy(proxyConnector.getProxyId()); + + if (networkProxyConfig != null) { + // key/value: remote repo ID/proxy info + networkProxies.put(proxyConnector.getTargetRepository().getId(), networkProxyConfig); + } + } + } + } + + // That's a browsing request so we can a mix of SNAPSHOT and release artifacts (especially with snapshots which + // can have released parent pom + if (readMetadataRequest.isBrowsingRequest()) { + remoteRepositories.addAll(repositoryRegistry.getRemoteRepositories()); + } + + ModelBuildingRequest req = + new DefaultModelBuildingRequest().setProcessPlugins(false).setPomFile(file.getFilePath().toFile()).setTwoPhaseBuilding( + false).setValidationLevel(ModelBuildingRequest.VALIDATION_LEVEL_MINIMAL); + + //MRM-1607. olamy this will resolve jdk profiles on the current running archiva jvm + req.setSystemProperties(System.getProperties()); + + // MRM-1411 + req.setModelResolver( + new RepositoryModelResolver(managedRepository, pathTranslator, wagonFactory, remoteRepositories, + networkProxies, managedRepository, mavenSystemManager, metadataReader)); + + Model model; + try { + model = builder.build(req).getEffectiveModel(); + } catch (ModelBuildingException e) { + String msg = "The artifact's POM file '" + file + "' was invalid: " + e.getMessage(); + + List 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! + // olamy really hackhish but fail with java profile so use error message + // || ( StringUtils.startsWith( problem.getMessage(), "Failed to determine Java version for profile" ) ) + // but setTwoPhaseBuilding(true) fix that + if (((problem.getException() instanceof FileNotFoundException + || problem.getException() instanceof NoSuchFileException + ) && e.getModelId() != null && + !e.getModelId().equals(problem.getModelId()))) { + log.warn("The artifact's parent POM file '{}' cannot be resolved. " + + "Using defaults for project version metadata..", file); + + ProjectVersionMetadata metadata = new ProjectVersionMetadata(); + metadata.setId(readMetadataRequest.getProjectVersion()); + + MavenProjectFacet facet = new MavenProjectFacet(); + facet.setGroupId(readMetadataRequest.getNamespace()); + facet.setArtifactId(readMetadataRequest.getProjectId()); + facet.setPackaging("jar"); + metadata.addFacet(facet); + + String errMsg = + "Error in resolving artifact's parent POM file. " + (problem.getException() == null + ? problem.getMessage() + : problem.getException().getMessage()); + RepositoryProblemFacet repoProblemFacet = new RepositoryProblemFacet(); + repoProblemFacet.setRepositoryId(readMetadataRequest.getRepositoryId()); + repoProblemFacet.setId(readMetadataRequest.getRepositoryId()); + repoProblemFacet.setMessage(errMsg); + repoProblemFacet.setProblem(errMsg); + repoProblemFacet.setProject(readMetadataRequest.getProjectId()); + repoProblemFacet.setVersion(readMetadataRequest.getProjectVersion()); + repoProblemFacet.setNamespace(readMetadataRequest.getNamespace()); + + metadata.addFacet(repoProblemFacet); + + return metadata; + } + } + + throw new RepositoryStorageMetadataInvalidException("invalid-pom", msg, e); + } + + // Check if the POM is in the correct location + boolean correctGroupId = readMetadataRequest.getNamespace().equals(model.getGroupId()); + boolean correctArtifactId = readMetadataRequest.getProjectId().equals(model.getArtifactId()); + boolean correctVersion = readMetadataRequest.getProjectVersion().equals(model.getVersion()); + if (!correctGroupId || !correctArtifactId || !correctVersion) { + StringBuilder message = new StringBuilder("Incorrect POM coordinates in '" + file + "':"); + if (!correctGroupId) { + message.append("\nIncorrect group ID: ").append(model.getGroupId()); + } + if (!correctArtifactId) { + message.append("\nIncorrect artifact ID: ").append(model.getArtifactId()); + } + if (!correctVersion) { + message.append("\nIncorrect version: ").append(model.getVersion()); + } + + throw new RepositoryStorageMetadataInvalidException("mislocated-pom", message.toString()); + } + + ProjectVersionMetadata metadata = new ProjectVersionMetadata(); + metadata.setCiManagement(convertCiManagement(model.getCiManagement())); + metadata.setDescription(model.getDescription()); + metadata.setId(readMetadataRequest.getProjectVersion()); + metadata.setIssueManagement(convertIssueManagement(model.getIssueManagement())); + metadata.setLicenses(convertLicenses(model.getLicenses())); + metadata.setMailingLists(convertMailingLists(model.getMailingLists())); + metadata.setDependencies(convertDependencies(model.getDependencies())); + metadata.setName(model.getName()); + metadata.setOrganization(convertOrganization(model.getOrganization())); + metadata.setScm(convertScm(model.getScm())); + metadata.setUrl(model.getUrl()); + metadata.setProperties( new HashMap( (Map) model.getProperties( ) ) ); + + MavenProjectFacet facet = new MavenProjectFacet(); + facet.setGroupId(model.getGroupId() != null ? model.getGroupId() : model.getParent().getGroupId()); + facet.setArtifactId(model.getArtifactId()); + facet.setPackaging(model.getPackaging()); + if (model.getParent() != null) { + MavenProjectParent parent = new MavenProjectParent(); + parent.setGroupId(model.getParent().getGroupId()); + parent.setArtifactId(model.getParent().getArtifactId()); + parent.setVersion(model.getParent().getVersion()); + facet.setParent(parent); + } + metadata.addFacet(facet); + + return metadata; + + + } + + public void setWagonFactory(WagonFactory wagonFactory) { + this.wagonFactory = wagonFactory; + } + + private List convertDependencies(List dependencies) { + List l = new ArrayList<>(); + for (Dependency dependency : dependencies) { + org.apache.archiva.metadata.model.Dependency newDependency = + new org.apache.archiva.metadata.model.Dependency(); + newDependency.setArtifactId(dependency.getArtifactId()); + newDependency.setClassifier(dependency.getClassifier()); + newDependency.setNamespace(dependency.getGroupId()); + newDependency.setOptional(dependency.isOptional()); + newDependency.setScope(dependency.getScope()); + newDependency.setSystemPath(dependency.getSystemPath()); + newDependency.setType(dependency.getType()); + newDependency.setVersion(dependency.getVersion()); + l.add(newDependency); + } + return l; + } + + private org.apache.archiva.metadata.model.Scm convertScm(Scm scm) { + org.apache.archiva.metadata.model.Scm newScm = null; + if (scm != null) { + newScm = new org.apache.archiva.metadata.model.Scm(); + newScm.setConnection(scm.getConnection()); + newScm.setDeveloperConnection(scm.getDeveloperConnection()); + newScm.setUrl(scm.getUrl()); + } + return newScm; + } + + private org.apache.archiva.metadata.model.Organization convertOrganization(Organization organization) { + org.apache.archiva.metadata.model.Organization org = null; + if (organization != null) { + org = new org.apache.archiva.metadata.model.Organization(); + org.setName(organization.getName()); + org.setUrl(organization.getUrl()); + } + return org; + } + + private List convertLicenses(List licenses) { + List l = new ArrayList<>(); + for (License license : licenses) { + org.apache.archiva.metadata.model.License newLicense = new org.apache.archiva.metadata.model.License(); + newLicense.setName(license.getName()); + newLicense.setUrl(license.getUrl()); + l.add(newLicense); + } + return l; + } + + private List convertMailingLists(List mailingLists) { + List l = new ArrayList<>(); + for (MailingList mailingList : mailingLists) { + org.apache.archiva.metadata.model.MailingList newMailingList = + new org.apache.archiva.metadata.model.MailingList(); + newMailingList.setName(mailingList.getName()); + newMailingList.setMainArchiveUrl(mailingList.getArchive()); + newMailingList.setPostAddress(mailingList.getPost()); + newMailingList.setSubscribeAddress(mailingList.getSubscribe()); + newMailingList.setUnsubscribeAddress(mailingList.getUnsubscribe()); + newMailingList.setOtherArchives(mailingList.getOtherArchives()); + l.add(newMailingList); + } + return l; + } + + private org.apache.archiva.metadata.model.IssueManagement convertIssueManagement(IssueManagement issueManagement) { + org.apache.archiva.metadata.model.IssueManagement im = null; + if (issueManagement != null) { + im = new org.apache.archiva.metadata.model.IssueManagement(); + im.setSystem(issueManagement.getSystem()); + im.setUrl(issueManagement.getUrl()); + } + return im; + } + + private org.apache.archiva.metadata.model.CiManagement convertCiManagement(CiManagement ciManagement) { + org.apache.archiva.metadata.model.CiManagement ci = null; + if (ciManagement != null) { + ci = new org.apache.archiva.metadata.model.CiManagement(); + ci.setSystem(ciManagement.getSystem()); + ci.setUrl(ciManagement.getUrl()); + } + return ci; + } + + @Override + public Collection listRootNamespaces(String repoId, Filter filter) + throws RepositoryStorageRuntimeException { + StorageAsset dir = getRepositoryBasedir(repoId); + + return getSortedFiles(dir, filter); + } + + private static Collection getSortedFiles(StorageAsset dir, Filter filter) { + + final Predicate dFilter = new DirectoryFilter(filter); + return dir.list().stream().filter(f -> f.isContainer()) + .filter(dFilter) + .map(path -> path.getName().toString()) + .sorted().collect(Collectors.toList()); + + } + + private StorageAsset getRepositoryBasedir(String repoId) + throws RepositoryStorageRuntimeException { + ManagedRepository repository = repositoryRegistry.getManagedRepository(repoId); + + return repository.getRoot(); + } + + @Override + public Collection listNamespaces(String repoId, String namespace, Filter filter) + throws RepositoryStorageRuntimeException { + StorageAsset dir = pathTranslator.toFile(getRepositoryBasedir(repoId), namespace); + if (!(dir.exists()) && !dir.isContainer()) { + return Collections.emptyList(); + } + // scan all the directories which are potential namespaces. Any directories known to be projects are excluded + Predicate dFilter = new DirectoryFilter(filter); + return dir.list().stream().filter(dFilter).filter(path -> !isProject(path, filter)).map(path -> path.getName().toString()) + .sorted().collect(Collectors.toList()); + } + + @Override + public Collection listProjects(String repoId, String namespace, Filter filter) + throws RepositoryStorageRuntimeException { + StorageAsset dir = pathTranslator.toFile(getRepositoryBasedir(repoId), namespace); + if (!(dir.exists() && dir.isContainer())) { + return Collections.emptyList(); + } + // scan all directories in the namespace, and only include those that are known to be projects + final Predicate dFilter = new DirectoryFilter(filter); + return dir.list().stream().filter(dFilter).filter(path -> isProject(path, filter)).map(path -> path.getName().toString()) + .sorted().collect(Collectors.toList()); + + } + + @Override + public Collection listProjectVersions(String repoId, String namespace, String projectId, + Filter filter) + throws RepositoryStorageRuntimeException { + StorageAsset dir = pathTranslator.toFile(getRepositoryBasedir(repoId), namespace, projectId); + if (!(dir.exists() && dir.isContainer())) { + return Collections.emptyList(); + } + + // all directories in a project directory can be considered a version + return getSortedFiles(dir, filter); + } + + @Override + public Collection readArtifactsMetadata(ReadMetadataRequest readMetadataRequest) + throws RepositoryStorageRuntimeException { + StorageAsset dir = pathTranslator.toFile(getRepositoryBasedir(readMetadataRequest.getRepositoryId()), + readMetadataRequest.getNamespace(), readMetadataRequest.getProjectId(), + readMetadataRequest.getProjectVersion()); + if (!(dir.exists() && dir.isContainer())) { + return Collections.emptyList(); + } + + // all files that are not metadata and not a checksum / signature are considered artifacts + final Predicate dFilter = new ArtifactDirectoryFilter(readMetadataRequest.getFilter()); + // Returns a map TRUE -> (success values), FALSE -> (Exceptions) + Map>> result = dir.list().stream().filter(dFilter).map(path -> { + try { + return Try.success(getArtifactFromFile(readMetadataRequest.getRepositoryId(), readMetadataRequest.getNamespace(), + readMetadataRequest.getProjectId(), readMetadataRequest.getProjectVersion(), + path)); + } catch (Exception e) { + log.debug("Could not create metadata for {}: {}", path, e.getMessage(), e); + return Try.failure(e); + } + } + ).collect(Collectors.groupingBy(Try::isSuccess)); + if (result.containsKey(Boolean.FALSE) && result.get(Boolean.FALSE).size() > 0 && (!result.containsKey(Boolean.TRUE) || result.get(Boolean.TRUE).size() == 0)) { + log.error("Could not get artifact metadata. Directory: {}. Number of errors {}.", dir, result.get(Boolean.FALSE).size()); + Try failure = result.get(Boolean.FALSE).get(0); + log.error("Sample exception {}", failure.getError().getMessage(), failure.getError()); + throw new RepositoryStorageRuntimeException(readMetadataRequest.getRepositoryId(), "Could not retrieve metadata of the files"); + } else { + if (!result.containsKey(Boolean.TRUE) || result.get(Boolean.TRUE) == null) { + return Collections.emptyList(); + } + return result.get(Boolean.TRUE).stream().map(tr -> tr.get()).collect(Collectors.toList()); + } + + } + + @Override + public ArtifactMetadata readArtifactMetadataFromPath(String repoId, String path) + throws RepositoryStorageRuntimeException { + ArtifactMetadata metadata = pathTranslator.getArtifactForPath(repoId, path); + + try { + populateArtifactMetadataFromFile(metadata, getRepositoryBasedir(repoId).resolve(path)); + } catch (IOException e) { + throw new RepositoryStorageRuntimeException(repoId, "Error during metadata retrieval of " + path + " :" + e.getMessage(), e); + } + + return metadata; + } + + private ArtifactMetadata getArtifactFromFile(String repoId, String namespace, String projectId, + String projectVersion, StorageAsset file) throws IOException { + ArtifactMetadata metadata = + pathTranslator.getArtifactFromId(repoId, namespace, projectId, projectVersion, file.getName()); + + populateArtifactMetadataFromFile(metadata, file); + + return metadata; + } + + @Override + public ItemSelector applyServerSideRelocation(ManagedRepository managedRepository, ItemSelector artifactSelector) + throws ProxyDownloadException { + if ("pom".equals(artifactSelector.getType())) { + return artifactSelector; + } + + // Build the artifact POM reference + BaseRepositoryContentLayout layout; + try + { + layout = managedRepository.getContent( ).getLayout( BaseRepositoryContentLayout.class ); + } + catch ( LayoutException e ) + { + throw new ProxyDownloadException( "Could not set layout " + e.getMessage( ), new HashMap<>( ) ); + } + + RepositoryType repositoryType = managedRepository.getType(); + if (!proxyRegistry.hasHandler(repositoryType)) { + throw new ProxyDownloadException("No proxy handler found for repository type " + repositoryType, new HashMap<>()); + } + + + + ItemSelector selector = ArchivaItemSelector.builder( ) + .withNamespace( artifactSelector.getNamespace( ) ) + .withProjectId( artifactSelector.getArtifactId( ) ) + .withArtifactId( artifactSelector.getArtifactId( ) ) + .withVersion( artifactSelector.getVersion( ) ) + .withArtifactVersion( artifactSelector.getVersion( ) ) + .withType( "pom" ).build( ); + + Artifact pom = layout.getArtifact( selector ); + + RepositoryProxyHandler proxyHandler = proxyRegistry.getHandler(repositoryType).get(0); + + // Get the artifact POM from proxied repositories if needed + proxyHandler.fetchFromProxies(managedRepository, pom); + + // Open and read the POM from the managed repo + + if (!pom.exists()) { + return artifactSelector; + } + + try { + // MavenXpp3Reader leaves the file open, so we need to close it ourselves. + + Model model; + try (Reader reader = Channels.newReader(pom.getAsset().getReadChannel(), Charset.defaultCharset().name())) { + model = MAVEN_XPP_3_READER.read(reader); + } + + DistributionManagement dist = model.getDistributionManagement(); + if (dist != null) { + Relocation relocation = dist.getRelocation(); + if (relocation != null) { + ArchivaItemSelector.Builder relocatedBuilder = ArchivaItemSelector.builder( ); + // artifact is relocated : update the repositoryPath + if (relocation.getGroupId() != null) { + relocatedBuilder.withNamespace( relocation.getGroupId( ) ); + } else { + relocatedBuilder.withNamespace( artifactSelector.getNamespace( ) ); + } + if (relocation.getArtifactId() != null) { + relocatedBuilder.withArtifactId( relocation.getArtifactId( ) ); + } else { + relocatedBuilder.withArtifactId( artifactSelector.getArtifactId( ) ); + } + if (relocation.getVersion() != null) + { + relocatedBuilder.withVersion( relocation.getVersion( ) ); + } else { + relocatedBuilder.withVersion( artifactSelector.getVersion( ) ); + } + return relocatedBuilder.withArtifactVersion( artifactSelector.getArtifactVersion( ) ) + .withClassifier( artifactSelector.getClassifier( ) ) + .withType( artifactSelector.getType( ) ) + .withProjectId( artifactSelector.getProjectId( ) ) + .withExtension( artifactSelector.getExtension( ) ) + .build( ); + } + } + } catch (IOException e) { + // Unable to read POM : ignore. + } catch (XmlPullParserException e) { + // Invalid POM : ignore + } + return artifactSelector; + } + + + @Override + public String getFilePath(String requestPath, org.apache.archiva.repository.ManagedRepository managedRepository) { + // managedRepository can be null + // extract artifact reference from url + // groupId:artifactId:version:packaging:classifier + //org/apache/archiva/archiva-checksum/1.4-M4-SNAPSHOT/archiva-checksum-1.4-M4-SNAPSHOT.jar + String logicalResource = null; + String requestPathInfo = StringUtils.defaultString(requestPath); + + //remove prefix ie /repository/blah becomes /blah + requestPathInfo = removePrefix(requestPathInfo); + + // Remove prefixing slash as the repository id doesn't contain it; + if (requestPathInfo.startsWith("/")) { + requestPathInfo = requestPathInfo.substring(1); + } + + int slash = requestPathInfo.indexOf('/'); + if (slash > 0) { + logicalResource = requestPathInfo.substring(slash); + + if (logicalResource.endsWith("/..")) { + logicalResource += "/"; + } + + if (logicalResource != null && logicalResource.startsWith("//")) { + logicalResource = logicalResource.substring(1); + } + + if (logicalResource == null) { + logicalResource = "/"; + } + } else { + logicalResource = "/"; + } + return logicalResource; + + } + + @Override + public String getFilePathWithVersion(final String requestPath, ManagedRepositoryContent managedRepositoryContent) + throws RelocationException + { + + if (StringUtils.endsWith(requestPath, METADATA_FILENAME)) { + return getFilePath(requestPath, managedRepositoryContent.getRepository()); + } + + String filePath = getFilePath(requestPath, managedRepositoryContent.getRepository()); + Artifact artifact; + try + { + ContentItem item = managedRepositoryContent.toItem( filePath ); + artifact = managedRepositoryContent.getLayout( BaseRepositoryContentLayout.class ).adaptItem( Artifact.class, item ); + } + catch ( LayoutException e ) + { + return filePath; + } + + if (VersionUtil.isGenericSnapshot(artifact.getArtifactVersion())) { + // read maven metadata to get last timestamp + StorageAsset metadataDir = managedRepositoryContent.getRepository().getAsset(filePath).getParent(); + if (!metadataDir.exists()) { + return filePath; + } + StorageAsset metadataFile = metadataDir.resolve(METADATA_FILENAME); + if (!metadataFile.exists()) { + return filePath; + } + ArchivaRepositoryMetadata archivaRepositoryMetadata = null; + try + { + archivaRepositoryMetadata = metadataReader.read(metadataFile); + } + catch ( RepositoryMetadataException e ) + { + log.error( "Could not read metadata {}", e.getMessage( ), e ); + return filePath; + } + int buildNumber = archivaRepositoryMetadata.getSnapshotVersion().getBuildNumber(); + String timestamp = archivaRepositoryMetadata.getSnapshotVersion().getTimestamp(); + + // MRM-1846 + if (buildNumber < 1 && timestamp == null) { + return filePath; + } + + // org/apache/archiva/archiva-checksum/1.4-M4-SNAPSHOT/archiva-checksum-1.4-M4-SNAPSHOT.jar + // -> archiva-checksum-1.4-M4-20130425.081822-1.jar + + filePath = StringUtils.replace(filePath, // + artifact.getId() // + + "-" + artifact.getVersion().getId(), // + artifact.getId() // + + "-" + StringUtils.remove(artifact.getArtifactVersion(), + "-" + VersionUtil.SNAPSHOT) // + + "-" + timestamp // + + "-" + buildNumber); + + throw new RelocationException("/repository/" + managedRepositoryContent.getRepository().getId() + + (StringUtils.startsWith(filePath, "/") ? "" : "/") + filePath, + RelocationException.RelocationType.TEMPORARY); + + } + + return filePath; + } + + //----------------------------- + // internal + //----------------------------- + + /** + * FIXME remove + * + * @param href + * @return + */ + private static String removePrefix(final String href) { + String[] parts = StringUtils.split(href, '/'); + parts = (String[]) ArrayUtils.subarray(parts, 1, parts.length); + if (parts == null || parts.length == 0) { + return "/"; + } + + String joinedString = StringUtils.join(parts, '/'); + if (href.endsWith("/")) { + joinedString = joinedString + "/"; + } + + return joinedString; + } + + private static void populateArtifactMetadataFromFile(ArtifactMetadata metadata, StorageAsset file) throws IOException { + metadata.setWhenGathered(ZonedDateTime.now(ZoneId.of("GMT"))); + metadata.setFileLastModified(file.getModificationTime().toEpochMilli()); + ChecksummedFile checksummedFile = new ChecksummedFile(file.getFilePath()); + try { + metadata.setMd5(checksummedFile.calculateChecksum(ChecksumAlgorithm.MD5)); + } catch (IOException e) { + log.error("Unable to checksum file {}: {},MD5", file, e.getMessage()); + } + try { + metadata.setSha1(checksummedFile.calculateChecksum(ChecksumAlgorithm.SHA1)); + } catch (IOException e) { + log.error("Unable to checksum file {}: {},SHA1", file, e.getMessage()); + } + metadata.setSize(file.getSize()); + } + + private boolean isProject(StorageAsset dir, Filter filter) { + // scan directories for a valid project version subdirectory, meaning this must be a project directory + final Predicate dFilter = new DirectoryFilter(filter); + boolean projFound = dir.list().stream().filter(dFilter) + .anyMatch(path -> isProjectVersion(path)); + if (projFound) { + return true; + } + + // if a metadata file is present, check if this is the "artifactId" directory, marking it as a project + ArchivaRepositoryMetadata metadata = readMetadata(dir); + if (metadata != null && dir.getName().toString().equals(metadata.getArtifactId())) { + return true; + } + + return false; + } + + private boolean isProjectVersion(StorageAsset dir) { + final String artifactId = dir.getParent().getName(); + final String projectVersion = dir.getName(); + + // check if there is a POM artifact file to ensure it is a version directory + + Predicate filter; + if (VersionUtil.isSnapshot(projectVersion)) { + filter = new PomFilenameFilter(artifactId, projectVersion); + } else { + final String pomFile = artifactId + "-" + projectVersion + ".pom"; + filter = new PomFileFilter(pomFile); + } + if (dir.list().stream().filter(f -> !f.isContainer()).anyMatch(filter)) { + return true; + } + // if a metadata file is present, check if this is the "version" directory, marking it as a project version + ArchivaRepositoryMetadata metadata = readMetadata(dir); + if (metadata != null && projectVersion.equals(metadata.getVersion())) { + return true; + } + + return false; + } + + private ArchivaRepositoryMetadata readMetadata(StorageAsset directory) { + ArchivaRepositoryMetadata metadata = null; + StorageAsset metadataFile = directory.resolve(METADATA_FILENAME); + if (metadataFile.exists()) { + try { + metadata = metadataReader.read(metadataFile); + } catch ( RepositoryMetadataException e ) + { + // Ignore missing or invalid metadata + } + } + return metadata; + } + + private static class DirectoryFilter + implements Predicate { + private final Filter filter; + + public DirectoryFilter(Filter filter) { + this.filter = filter; + } + + @Override + public boolean test(StorageAsset dir) { + final String name = dir.getName(); + if (!filter.accept(name)) { + return false; + } else if (name.startsWith(".")) { + return false; + } else if (!dir.isContainer()) { + return false; + } + return true; + } + } + + private static class ArtifactDirectoryFilter + implements Predicate { + private final Filter filter; + + private ArtifactDirectoryFilter(Filter filter) { + this.filter = filter; + } + + @Override + public boolean test(StorageAsset file) { + final Set checksumExts = ChecksumAlgorithm.getAllExtensions(); + final String path = file.getPath(); + final String name = file.getName(); + final String extension = StringUtils.substringAfterLast(name, ".").toLowerCase(); + // TODO compare to logic in maven-repository-layer + if (file.isContainer()) { + return false; + } else if (!filter.accept(name)) { + return false; + } else if (name.startsWith(".") || path.contains("/.") ) { + return false; + } else if (checksumExts.contains(extension)) { + return false; + } else if (Arrays.binarySearch(IGNORED_FILES, name) >= 0) { + return false; + } + // some files from remote repositories can have name like maven-metadata-archiva-vm-all-public.xml + else if (StringUtils.startsWith(name, METADATA_FILENAME_START) && StringUtils.endsWith(name, ".xml")) { + return false; + } + + return true; + + } + } + + + private static final class PomFilenameFilter + implements Predicate { + + private final String artifactId, projectVersion; + + private PomFilenameFilter(String artifactId, String projectVersion) { + this.artifactId = artifactId; + this.projectVersion = projectVersion; + } + + @Override + public boolean test(StorageAsset dir) { + final String name = dir.getName(); + if (name.startsWith(artifactId + "-") && name.endsWith(".pom")) { + String v = name.substring(artifactId.length() + 1, name.length() - 4); + v = VersionUtil.getBaseVersion(v); + if (v.equals(projectVersion)) { + return true; + } + } + return false; + } + + } + + private static class PomFileFilter + implements Predicate { + private final String pomFile; + + private PomFileFilter(String pomFile) { + this.pomFile = pomFile; + } + + @Override + public boolean test(StorageAsset dir) { + return pomFile.equals(dir.getName()); + } + } + +} diff --git a/archiva-modules/archiva-maven/archiva-maven-repository/src/main/java/org/apache/archiva/maven/repository/metadata/storage/MavenArtifactFacetFactory.java b/archiva-modules/archiva-maven/archiva-maven-repository/src/main/java/org/apache/archiva/maven/repository/metadata/storage/MavenArtifactFacetFactory.java new file mode 100644 index 000000000..fe21e09aa --- /dev/null +++ b/archiva-modules/archiva-maven/archiva-maven-repository/src/main/java/org/apache/archiva/maven/repository/metadata/storage/MavenArtifactFacetFactory.java @@ -0,0 +1,47 @@ +package org.apache.archiva.maven.repository.metadata.storage; + +/* + * 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.maven.metadata.model.MavenArtifactFacet; +import org.apache.archiva.metadata.model.facets.AbstractMetadataFacetFactory; +import org.springframework.stereotype.Service; + +/** + * + */ +@Service("metadataFacetFactory#org.apache.archiva.metadata.repository.storage.maven2.artifact") +public class MavenArtifactFacetFactory + extends AbstractMetadataFacetFactory +{ + public MavenArtifactFacetFactory() { + super( MavenArtifactFacet.class); + } + + @Override + public MavenArtifactFacet createMetadataFacet() + { + return new MavenArtifactFacet(); + } + + @Override + public MavenArtifactFacet createMetadataFacet( String repositoryId, String name ) + { + throw new UnsupportedOperationException( "There is no valid name for artifact facets" ); + } +} \ No newline at end of file diff --git a/archiva-modules/archiva-maven/archiva-maven-repository/src/main/java/org/apache/archiva/maven/repository/metadata/storage/MavenProjectFacet.java b/archiva-modules/archiva-maven/archiva-maven-repository/src/main/java/org/apache/archiva/maven/repository/metadata/storage/MavenProjectFacet.java new file mode 100644 index 000000000..1b455a88b --- /dev/null +++ b/archiva-modules/archiva-maven/archiva-maven-repository/src/main/java/org/apache/archiva/maven/repository/metadata/storage/MavenProjectFacet.java @@ -0,0 +1,163 @@ +package org.apache.archiva.maven.repository.metadata.storage; + +/* + * 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.metadata.model.MetadataFacet; + +import java.util.HashMap; +import java.util.Map; + +public class MavenProjectFacet + implements MetadataFacet +{ + private String groupId; + + private String artifactId; + + private MavenProjectParent parent; + + private String packaging; + + public static final String FACET_ID = "org.apache.archiva.metadata.repository.storage.maven2.project"; + + public String getGroupId() + { + return groupId; + } + + public void setGroupId( String groupId ) + { + this.groupId = groupId; + } + + public String getArtifactId() + { + return artifactId; + } + + public void setArtifactId( String artifactId ) + { + this.artifactId = artifactId; + } + + public MavenProjectParent getParent() + { + return parent; + } + + public void setParent( MavenProjectParent parent ) + { + this.parent = parent; + } + + public String getPackaging() + { + return packaging; + } + + public void setPackaging( String packaging ) + { + this.packaging = packaging; + } + + @Override + public String getFacetId() + { + return FACET_ID; + } + + @Override + public String getName() + { + // TODO: not needed, perhaps version metadata facet should be separate interface? + return null; + } + + @Override + public Map toProperties() + { + HashMap properties = new HashMap<>(); + properties.put( "groupId", groupId ); + properties.put( "artifactId", artifactId ); + properties.put( "packaging", packaging ); + if ( parent != null ) + { + properties.put( "parent.groupId", parent.getGroupId() ); + properties.put( "parent.artifactId", parent.getArtifactId() ); + properties.put( "parent.version", parent.getVersion() ); + } + return properties; + } + + @Override + public void fromProperties( Map properties ) + { + groupId = properties.get( "groupId" ); + artifactId = properties.get( "artifactId" ); + packaging = properties.get( "packaging" ); + String parentArtifactId = properties.get( "parent.artifactId" ); + if ( parentArtifactId != null ) + { + MavenProjectParent parent = new MavenProjectParent(); + parent.setGroupId( properties.get( "parent.groupId" ) ); + parent.setArtifactId( parentArtifactId ); + parent.setVersion( properties.get( "parent.version" ) ); + this.parent = parent; + } + } + + @Override + public boolean equals( Object o ) + { + if ( this == o ) + { + return true; + } + if ( !( o instanceof MavenProjectFacet ) ) + { + return false; + } + + MavenProjectFacet that = (MavenProjectFacet) o; + + if ( !artifactId.equals( that.artifactId ) ) + { + return false; + } + if ( !groupId.equals( that.groupId ) ) + { + return false; + } + if ( !packaging.equals( that.packaging ) ) + { + return false; + } + + return true; + } + + @Override + public int hashCode() + { + int result = groupId.hashCode(); + result = 31 * result + artifactId.hashCode(); + result = 31 * result + packaging.hashCode(); + return result; + } +} diff --git a/archiva-modules/archiva-maven/archiva-maven-repository/src/main/java/org/apache/archiva/maven/repository/metadata/storage/MavenProjectFacetFactory.java b/archiva-modules/archiva-maven/archiva-maven-repository/src/main/java/org/apache/archiva/maven/repository/metadata/storage/MavenProjectFacetFactory.java new file mode 100644 index 000000000..7d9a6da8b --- /dev/null +++ b/archiva-modules/archiva-maven/archiva-maven-repository/src/main/java/org/apache/archiva/maven/repository/metadata/storage/MavenProjectFacetFactory.java @@ -0,0 +1,46 @@ +package org.apache.archiva.maven.repository.metadata.storage; + +/* + * 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.metadata.model.facets.AbstractMetadataFacetFactory; +import org.springframework.stereotype.Service; + +/** + * + */ +@Service( "metadataFacetFactory#org.apache.archiva.metadata.repository.storage.maven2.project" ) +public class MavenProjectFacetFactory + extends AbstractMetadataFacetFactory +{ + public MavenProjectFacetFactory() { + super( MavenProjectFacet.class ); + } + + @Override + public MavenProjectFacet createMetadataFacet() + { + return new MavenProjectFacet(); + } + + @Override + public MavenProjectFacet createMetadataFacet( String repositoryId, String name ) + { + throw new UnsupportedOperationException( "There is no valid name for project version facets" ); + } +} diff --git a/archiva-modules/archiva-maven/archiva-maven-repository/src/main/java/org/apache/archiva/maven/repository/metadata/storage/MavenProjectParent.java b/archiva-modules/archiva-maven/archiva-maven-repository/src/main/java/org/apache/archiva/maven/repository/metadata/storage/MavenProjectParent.java new file mode 100644 index 000000000..fe80af547 --- /dev/null +++ b/archiva-modules/archiva-maven/archiva-maven-repository/src/main/java/org/apache/archiva/maven/repository/metadata/storage/MavenProjectParent.java @@ -0,0 +1,58 @@ +package org.apache.archiva.maven.repository.metadata.storage; + +/* + * 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. + */ + +public class MavenProjectParent +{ + private String groupId; + + private String artifactId; + + private String version; + + public String getVersion() + { + return version; + } + + public void setVersion( String version ) + { + this.version = version; + } + + public String getArtifactId() + { + return artifactId; + } + + public void setArtifactId( String artifactId ) + { + this.artifactId = artifactId; + } + + public String getGroupId() + { + return groupId; + } + + public void setGroupId( String groupId ) + { + this.groupId = groupId; + } +} diff --git a/archiva-modules/archiva-maven/archiva-maven-repository/src/main/java/org/apache/archiva/maven/repository/metadata/storage/RepositoryModelResolver.java b/archiva-modules/archiva-maven/archiva-maven-repository/src/main/java/org/apache/archiva/maven/repository/metadata/storage/RepositoryModelResolver.java new file mode 100644 index 000000000..9ad3a6065 --- /dev/null +++ b/archiva-modules/archiva-maven/archiva-maven-repository/src/main/java/org/apache/archiva/maven/repository/metadata/storage/RepositoryModelResolver.java @@ -0,0 +1,597 @@ +package org.apache.archiva.maven.repository.metadata.storage; + +/* + * 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.utils.VersionUtil; +import org.apache.archiva.maven.metadata.MavenMetadataReader; +import org.apache.archiva.metadata.repository.storage.RepositoryPathTranslator; +import org.apache.archiva.model.ArchivaRepositoryMetadata; +import org.apache.archiva.model.SnapshotVersion; +import org.apache.archiva.maven.common.proxy.WagonFactory; +import org.apache.archiva.maven.common.proxy.WagonFactoryException; +import org.apache.archiva.maven.common.proxy.WagonFactoryRequest; +import org.apache.archiva.proxy.model.NetworkProxy; +import org.apache.archiva.repository.ManagedRepository; +import org.apache.archiva.repository.RemoteRepository; +import org.apache.archiva.repository.RepositoryCredentials; +import org.apache.archiva.maven.repository.MavenSystemManager; +import org.apache.archiva.repository.metadata.RepositoryMetadataException; +import org.apache.archiva.repository.storage.StorageAsset; +import org.apache.commons.lang3.StringUtils; +import org.apache.http.auth.UsernamePasswordCredentials; +import org.apache.maven.model.Dependency; +import org.apache.maven.model.Parent; +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.eclipse.aether.RepositorySystemSession; +import org.eclipse.aether.artifact.Artifact; +import org.eclipse.aether.artifact.DefaultArtifact; +import org.eclipse.aether.impl.VersionRangeResolver; +import org.eclipse.aether.resolution.VersionRangeRequest; +import org.eclipse.aether.resolution.VersionRangeResolutionException; +import org.eclipse.aether.resolution.VersionRangeResult; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Path; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +public class RepositoryModelResolver + implements ModelResolver +{ + + private final Map networkProxyMap = new HashMap<>(); + + private RepositorySystemSession session; + private VersionRangeResolver versionRangeResolver; + + private StorageAsset basedir; + + private RepositoryPathTranslator pathTranslator; + + private WagonFactory wagonFactory; + + private List remoteRepositories; + + private ManagedRepository targetRepository; + + private static final Logger log = LoggerFactory.getLogger( RepositoryModelResolver.class ); + + private static final String METADATA_FILENAME = "maven-metadata.xml"; + + private MavenSystemManager mavenSystemManager; + + private MavenMetadataReader metadataReader; + + + + private ManagedRepository managedRepository; + + public RepositoryModelResolver(StorageAsset basedir, RepositoryPathTranslator pathTranslator) + { + this.basedir = basedir; + + this.pathTranslator = pathTranslator; + + } + + public RepositoryModelResolver(ManagedRepository managedRepository, RepositoryPathTranslator pathTranslator, + WagonFactory wagonFactory, List remoteRepositories, + Map networkProxiesMap, ManagedRepository targetRepository, + MavenSystemManager mavenSystemManager, MavenMetadataReader metadataReader) + { + this( managedRepository.getRoot(), pathTranslator ); + + this.managedRepository = managedRepository; + + this.wagonFactory = wagonFactory; + + this.remoteRepositories = remoteRepositories; + + this.networkProxyMap.clear(); + this.networkProxyMap.putAll(networkProxiesMap); + + this.targetRepository = targetRepository; + + this.session = MavenSystemManager.newRepositorySystemSession( managedRepository.getRoot().getFilePath().toString() ); + + this.versionRangeResolver = mavenSystemManager.getLocator().getService(VersionRangeResolver.class); + + this.mavenSystemManager = mavenSystemManager; + this.metadataReader = metadataReader; + } + + + @Override + 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 + + StorageAsset model = pathTranslator.toFile( basedir, groupId, artifactId, version, filename ); + + if ( !model.exists() ) + { + /** + * + */ + // is a SNAPSHOT ? so we can try to find locally before asking remote repositories. + if ( StringUtils.contains( version, VersionUtil.SNAPSHOT ) ) + { + Path localSnapshotModel = findTimeStampedSnapshotPom( groupId, artifactId, version, model.getParent().getFilePath() ); + if ( localSnapshotModel != null ) + { + return new FileModelSource( localSnapshotModel.toFile() ); + } + + } + + for ( RemoteRepository remoteRepository : remoteRepositories ) + { + try + { + boolean success = getModelFromProxy( remoteRepository, groupId, artifactId, version, filename ); + if ( success && model.exists() ) + { + log.info( "Model '{}' successfully retrieved from remote repository '{}'", + model.getPath(), remoteRepository.getId() ); + break; + } + } + catch ( ResourceDoesNotExistException e ) + { + log.info( + "An exception was caught while attempting to retrieve model '{}' from remote repository '{}'.Reason:{}", + model.getPath(), remoteRepository.getId(), e.getMessage() ); + } + catch ( Exception e ) + { + log.warn( + "An exception was caught while attempting to retrieve model '{}' from remote repository '{}'.Reason:{}", + model.getPath(), remoteRepository.getId(), e.getMessage() ); + + continue; + } + } + } + + return new FileModelSource( model.getFilePath().toFile() ); + } + + public ModelSource resolveModel(Parent parent) throws UnresolvableModelException { + try { + Artifact artifact = new DefaultArtifact(parent.getGroupId(), parent.getArtifactId(), "", "pom", parent.getVersion()); + VersionRangeRequest versionRangeRequest; + versionRangeRequest = new VersionRangeRequest(artifact, null, null); + VersionRangeResult versionRangeResult = this.versionRangeResolver.resolveVersionRange(this.session, versionRangeRequest); + if (versionRangeResult.getHighestVersion() == null) { + throw new UnresolvableModelException(String.format("No versions matched the requested parent version range '%s'", parent.getVersion()), parent.getGroupId(), parent.getArtifactId(), parent.getVersion()); + } else if (versionRangeResult.getVersionConstraint() != null && versionRangeResult.getVersionConstraint().getRange() != null && versionRangeResult.getVersionConstraint().getRange().getUpperBound() == null) { + throw new UnresolvableModelException(String.format("The requested parent version range '%s' does not specify an upper bound", parent.getVersion()), parent.getGroupId(), parent.getArtifactId(), parent.getVersion()); + } else { + parent.setVersion(versionRangeResult.getHighestVersion().toString()); + return this.resolveModel(parent.getGroupId(), parent.getArtifactId(), parent.getVersion()); + } + } catch ( VersionRangeResolutionException var5) { + throw new UnresolvableModelException(var5.getMessage(), parent.getGroupId(), parent.getArtifactId(), parent.getVersion(), var5); + } + } + + public ModelSource resolveModel(Dependency dependency) throws UnresolvableModelException { + try { + Artifact artifact = new DefaultArtifact(dependency.getGroupId(), dependency.getArtifactId(), "", "pom", dependency.getVersion()); + VersionRangeRequest versionRangeRequest = new VersionRangeRequest(artifact, null, null); + VersionRangeResult versionRangeResult = this.versionRangeResolver.resolveVersionRange(this.session, versionRangeRequest); + if (versionRangeResult.getHighestVersion() == null) { + throw new UnresolvableModelException(String.format("No versions matched the requested dependency version range '%s'", dependency.getVersion()), dependency.getGroupId(), dependency.getArtifactId(), dependency.getVersion()); + } else if (versionRangeResult.getVersionConstraint() != null && versionRangeResult.getVersionConstraint().getRange() != null && versionRangeResult.getVersionConstraint().getRange().getUpperBound() == null) { + throw new UnresolvableModelException(String.format("The requested dependency version range '%s' does not specify an upper bound", dependency.getVersion()), dependency.getGroupId(), dependency.getArtifactId(), dependency.getVersion()); + } else { + dependency.setVersion(versionRangeResult.getHighestVersion().toString()); + return this.resolveModel(dependency.getGroupId(), dependency.getArtifactId(), dependency.getVersion()); + } + } catch (VersionRangeResolutionException var5) { + throw new UnresolvableModelException(var5.getMessage(), dependency.getGroupId(), dependency.getArtifactId(), dependency.getVersion(), var5); + } + } + + protected Path findTimeStampedSnapshotPom( String groupId, String artifactId, String version, + Path parentDirectory ) + { + + // reading metadata if there + Path mavenMetadata = parentDirectory.resolve( METADATA_FILENAME ); + if ( Files.exists(mavenMetadata) ) + { + try + { + ArchivaRepositoryMetadata archivaRepositoryMetadata = metadataReader.read( mavenMetadata ); + SnapshotVersion snapshotVersion = archivaRepositoryMetadata.getSnapshotVersion(); + if ( snapshotVersion != null ) + { + String lastVersion = snapshotVersion.getTimestamp(); + int buildNumber = snapshotVersion.getBuildNumber(); + String snapshotPath = + StringUtils.replaceChars( groupId, '.', '/' ) + '/' + artifactId + '/' + version + '/' + + artifactId + '-' + StringUtils.remove( version, "-" + VersionUtil.SNAPSHOT ) + '-' + + lastVersion + '-' + buildNumber + ".pom"; + + log.debug( "use snapshot path {} for maven coordinate {}:{}:{}", snapshotPath, groupId, artifactId, + version ); + + StorageAsset model = basedir.resolve( snapshotPath ); + //model = pathTranslator.toFile( basedir, groupId, artifactId, lastVersion, filename ); + if ( model.exists() ) + { + return model.getFilePath(); + } + } + } + catch ( RepositoryMetadataException e ) + { + log.warn( "fail to read {}, {}", mavenMetadata.toAbsolutePath(), e.getCause() ); + } + } + + return null; + } + + @Override + public void addRepository( Repository repository ) + throws InvalidRepositoryException + { + // we just ignore repositories outside of the current one for now + // TODO: it'd be nice to look them up from Archiva's set, but we want to do that by URL / mapping, not just the + // ID since they will rarely match + } + + @Override + public void addRepository( Repository repository, boolean b ) throws InvalidRepositoryException + { + + } + + @Override + public ModelResolver newCopy() + { + return new RepositoryModelResolver( managedRepository, pathTranslator, wagonFactory, remoteRepositories, + networkProxyMap, targetRepository, mavenSystemManager, metadataReader); + } + + // FIXME: 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( RemoteRepository remoteRepository, String groupId, String artifactId, + String version, String filename ) + throws AuthorizationException, TransferFailedException, ResourceDoesNotExistException, WagonFactoryException, + IOException, RepositoryMetadataException + { + boolean success = false; + Path tmpMd5 = null; + Path tmpSha1 = null; + Path tmpResource = null; + String artifactPath = pathTranslator.toPath( groupId, artifactId, version, filename ); + Path resource = targetRepository.getRoot().getFilePath().resolve( artifactPath ); + + Path workingDirectory = createWorkingDirectory( targetRepository.getLocation().toString() ); + try + { + Wagon wagon = null; + try + { + String protocol = getProtocol( remoteRepository.getLocation().toString() ); + final NetworkProxy networkProxy = this.networkProxyMap.get( remoteRepository.getId() ); + + wagon = wagonFactory.getWagon( + new WagonFactoryRequest( "wagon#" + protocol, remoteRepository.getExtraHeaders() ).networkProxy( + networkProxy ) + ); + + if ( wagon == null ) + { + throw new RuntimeException( "Unsupported remote repository protocol: " + protocol ); + } + + boolean connected = connectToRepository( wagon, remoteRepository ); + if ( connected ) + { + tmpResource = workingDirectory.resolve( filename ); + + if ( VersionUtil.isSnapshot( version ) ) + { + // get the metadata first! + Path tmpMetadataResource = workingDirectory.resolve( METADATA_FILENAME ); + + String metadataPath = + StringUtils.substringBeforeLast( artifactPath, "/" ) + "/" + METADATA_FILENAME; + + wagon.get( addParameters( metadataPath, remoteRepository ), tmpMetadataResource.toFile() ); + + log.debug( "Successfully downloaded metadata." ); + + ArchivaRepositoryMetadata metadata = metadataReader.read( tmpMetadataResource ); + + // re-adjust to timestamp if present, otherwise retain the original -SNAPSHOT filename + SnapshotVersion snapshotVersion = metadata.getSnapshotVersion(); + String timestampVersion = version; + if ( snapshotVersion != null ) + { + timestampVersion = timestampVersion.substring( 0, timestampVersion.length() + - 8 ); // remove SNAPSHOT from end + timestampVersion = timestampVersion + snapshotVersion.getTimestamp() + "-" + + snapshotVersion.getBuildNumber(); + + filename = artifactId + "-" + timestampVersion + ".pom"; + + artifactPath = pathTranslator.toPath( groupId, artifactId, version, filename ); + + log.debug( "New artifactPath :{}", artifactPath ); + } + } + + log.info( "Retrieving {} from {}", artifactPath, remoteRepository.getName() ); + + wagon.get( addParameters( artifactPath, remoteRepository ), tmpResource.toFile() ); + + 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.toAbsolutePath().toString().intern() ) + { + Path directory = resource.getParent(); + moveFileIfExists( tmpMd5, directory ); + moveFileIfExists( tmpSha1, directory ); + moveFileIfExists( tmpResource, directory ); + success = true; + } + } + } + finally + { + org.apache.archiva.common.utils.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, RemoteRepository remoteRepository ) + { + boolean connected; + + final NetworkProxy proxyConnector = this.networkProxyMap.get( remoteRepository.getId() ); + ProxyInfo networkProxy = null; + if ( proxyConnector != null ) + { + networkProxy = new ProxyInfo(); + networkProxy.setType( proxyConnector.getProtocol() ); + networkProxy.setHost( proxyConnector.getHost() ); + networkProxy.setPort( proxyConnector.getPort() ); + networkProxy.setUserName( proxyConnector.getUsername() ); + networkProxy.setPassword( new String(proxyConnector.getPassword()) ); + + String msg = "Using network proxy " + networkProxy.getHost() + ":" + networkProxy.getPort() + + " to connect to remote repository " + remoteRepository.getLocation(); + 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; + RepositoryCredentials creds = remoteRepository.getLoginCredentials(); + String username = ""; + String password = ""; + if (creds instanceof UsernamePasswordCredentials) { + UsernamePasswordCredentials c = (UsernamePasswordCredentials) creds; + username = c.getUserName(); + password = c.getPassword(); + } + + if ( StringUtils.isNotBlank( username ) && StringUtils.isNotBlank( password ) ) + { + log.debug( "Using username {} to connect to remote repository {}", username, remoteRepository.getLocation() ); + authInfo = new AuthenticationInfo(); + authInfo.setUserName( username ); + authInfo.setPassword( password ); + } + + int timeoutInMilliseconds = ((int)remoteRepository.getTimeout().getSeconds())*1000; + // FIXME olamy having 2 config values + // Set timeout + wagon.setReadTimeout( timeoutInMilliseconds ); + wagon.setTimeout( timeoutInMilliseconds ); + + try + { + org.apache.maven.wagon.repository.Repository wagonRepository = + new org.apache.maven.wagon.repository.Repository( remoteRepository.getId(), remoteRepository.getLocation().toString() ); + if ( networkProxy != null ) + { + wagon.connect( wagonRepository, authInfo, networkProxy ); + } + else + { + wagon.connect( wagonRepository, authInfo ); + } + connected = true; + } + catch ( ConnectionException | AuthenticationException e ) + { + log.error( "Could not connect to {}:{} ", remoteRepository.getName(), e.getMessage() ); + connected = false; + } + + return connected; + } + + /** + * + * @param wagon The wagon instance that should be connected. + * @param remoteRepository The repository from where the checksum file should be retrieved + * @param remotePath The remote path of the artifact (without extension) + * @param resource The local artifact (without extension) + * @param workingDir The working directory where the downloaded file should be placed to + * @param ext The extension of th checksum file + * @return The file where the data has been downloaded to. + * @throws AuthorizationException + * @throws TransferFailedException + * @throws ResourceDoesNotExistException + */ + private Path transferChecksum( final Wagon wagon, final RemoteRepository remoteRepository, + final String remotePath, final Path resource, + final Path workingDir, final String ext ) + throws AuthorizationException, TransferFailedException, ResourceDoesNotExistException + { + Path destFile = workingDir.resolve( resource.getFileName() + ext ); + String remoteChecksumPath = remotePath + ext; + + log.info( "Retrieving {} from {}", remoteChecksumPath, remoteRepository.getName() ); + + wagon.get( addParameters( remoteChecksumPath, remoteRepository ), destFile.toFile() ); + + log.debug( "Downloaded successfully." ); + + return destFile; + } + + private String getProtocol( String url ) + { + String protocol = StringUtils.substringBefore( url, ":" ); + + return protocol; + } + + private Path createWorkingDirectory( String targetRepository ) + throws IOException + { + return Files.createTempDirectory( "temp" ); + } + + private void moveFileIfExists( Path fileToMove, Path directory ) + { + if ( fileToMove != null && Files.exists(fileToMove) ) + { + Path newLocation = directory.resolve( fileToMove.getFileName() ); + try { + Files.deleteIfExists(newLocation); + } catch (IOException e) { + throw new RuntimeException( + "Unable to overwrite existing target file: " + newLocation.toAbsolutePath(), e ); + } + + try { + Files.createDirectories(newLocation.getParent()); + } catch (IOException e) { + e.printStackTrace(); + } + try { + Files.move(fileToMove, newLocation ); + } catch (IOException e) { + try { + Files.copy(fileToMove, newLocation); + } catch (IOException e1) { + if (Files.exists(newLocation)) { + log.error( "Tried to copy file {} to {} but file with this name already exists.", + fileToMove.getFileName(), newLocation.toAbsolutePath() ); + } else { + throw new RuntimeException( + "Cannot copy tmp file " + fileToMove.toAbsolutePath() + " to its final location", e ); + } + } + } finally { + org.apache.archiva.common.utils.FileUtils.deleteQuietly(fileToMove); + } + } + } + + protected String addParameters( String path, RemoteRepository remoteRepository ) + { + if ( remoteRepository.getExtraParameters().isEmpty() ) + { + return path; + } + + boolean question = false; + + StringBuilder res = new StringBuilder( path == null ? "" : path ); + + for ( Map.Entry entry : remoteRepository.getExtraParameters().entrySet() ) + { + if ( !question ) + { + res.append( '?' ).append( entry.getKey() ).append( '=' ).append( entry.getValue() ); + } + } + + return res.toString(); + } +} diff --git a/archiva-modules/archiva-maven/archiva-maven-repository/src/main/java/org/apache/archiva/repository/maven/MavenManagedRepository.java b/archiva-modules/archiva-maven/archiva-maven-repository/src/main/java/org/apache/archiva/repository/maven/MavenManagedRepository.java deleted file mode 100644 index eea28df47..000000000 --- a/archiva-modules/archiva-maven/archiva-maven-repository/src/main/java/org/apache/archiva/repository/maven/MavenManagedRepository.java +++ /dev/null @@ -1,147 +0,0 @@ -package org.apache.archiva.repository.maven; - -/* - * 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.filelock.DefaultFileLockManager; -import org.apache.archiva.common.filelock.FileLockManager; -import org.apache.archiva.indexer.ArchivaIndexingContext; -import org.apache.archiva.repository.ReleaseScheme; -import org.apache.archiva.repository.RepositoryCapabilities; -import org.apache.archiva.repository.RepositoryRequestInfo; -import org.apache.archiva.repository.RepositoryState; -import org.apache.archiva.repository.RepositoryType; -import org.apache.archiva.repository.StandardCapabilities; -import org.apache.archiva.repository.UnsupportedFeatureException; -import org.apache.archiva.repository.base.managed.AbstractManagedRepository; -import org.apache.archiva.repository.features.ArtifactCleanupFeature; -import org.apache.archiva.repository.features.IndexCreationFeature; -import org.apache.archiva.repository.features.RepositoryFeature; -import org.apache.archiva.repository.features.StagingRepositoryFeature; -import org.apache.archiva.repository.maven.content.MavenRepositoryRequestInfo; -import org.apache.archiva.repository.storage.fs.FilesystemStorage; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import java.io.IOException; -import java.nio.file.Path; -import java.util.Locale; - -/** - * Maven2 managed repository implementation. - */ -public class MavenManagedRepository extends AbstractManagedRepository -{ - - private static final Logger log = LoggerFactory.getLogger( MavenManagedRepository.class ); - - public static final String DEFAULT_LAYOUT = "default"; - public static final String LEGACY_LAYOUT = "legacy"; - private ArtifactCleanupFeature artifactCleanupFeature = new ArtifactCleanupFeature( ); - private IndexCreationFeature indexCreationFeature; - private StagingRepositoryFeature stagingRepositoryFeature = new StagingRepositoryFeature( ); - - - - private static final RepositoryCapabilities CAPABILITIES = new StandardCapabilities( - new ReleaseScheme[] { ReleaseScheme.RELEASE, ReleaseScheme.SNAPSHOT }, - new String[] { DEFAULT_LAYOUT, LEGACY_LAYOUT}, - new String[] {}, - new String[] {ArtifactCleanupFeature.class.getName(), IndexCreationFeature.class.getName(), - StagingRepositoryFeature.class.getName()}, - true, - true, - true, - true, - false - ); - - public MavenManagedRepository(String id, String name, FilesystemStorage storage) - { - - super( RepositoryType.MAVEN, id, name, storage); - this.indexCreationFeature = new IndexCreationFeature(this, this); - setLocation(storage.getRoot().getFilePath().toUri()); - setLastState( RepositoryState.CREATED ); - } - - public MavenManagedRepository( Locale primaryLocale, String id, String name, FilesystemStorage storage ) - { - super( primaryLocale, RepositoryType.MAVEN, id, name, storage ); - setLocation(storage.getRoot().getFilePath().toUri()); - setLastState( RepositoryState.CREATED ); - } - - @Override - public RepositoryCapabilities getCapabilities( ) - { - return CAPABILITIES; - } - - - @SuppressWarnings( "unchecked" ) - @Override - public > RepositoryFeature getFeature( Class clazz ) throws UnsupportedFeatureException - { - if (ArtifactCleanupFeature.class.equals( clazz )) - { - return (RepositoryFeature) artifactCleanupFeature; - } else if (IndexCreationFeature.class.equals(clazz)) { - return (RepositoryFeature) indexCreationFeature; - } else if (StagingRepositoryFeature.class.equals(clazz)) { - return (RepositoryFeature) stagingRepositoryFeature; - } else { - throw new UnsupportedFeatureException( ); - } - } - - @Override - public > boolean supportsFeature( Class clazz ) - { - if (ArtifactCleanupFeature.class.equals(clazz) || - IndexCreationFeature.class.equals(clazz) || - StagingRepositoryFeature.class.equals(clazz)) { - return true; - } - return false; - } - - @Override - public boolean hasIndex( ) - { - return indexCreationFeature.hasIndex(); - } - - @Override - public RepositoryRequestInfo getRequestInfo() { - return new MavenRepositoryRequestInfo(this); - } - - public static MavenManagedRepository newLocalInstance(String id, String name, Path basePath) throws IOException { - FileLockManager lockManager = new DefaultFileLockManager(); - FilesystemStorage storage = new FilesystemStorage(basePath.resolve(id), lockManager); - return new MavenManagedRepository(id, name, storage); - } - - @Override - public void setIndexingContext(ArchivaIndexingContext context) { - super.setIndexingContext(context); - } - -} diff --git a/archiva-modules/archiva-maven/archiva-maven-repository/src/main/java/org/apache/archiva/repository/maven/MavenRemoteRepository.java b/archiva-modules/archiva-maven/archiva-maven-repository/src/main/java/org/apache/archiva/repository/maven/MavenRemoteRepository.java deleted file mode 100644 index f4e8720ae..000000000 --- a/archiva-modules/archiva-maven/archiva-maven-repository/src/main/java/org/apache/archiva/repository/maven/MavenRemoteRepository.java +++ /dev/null @@ -1,126 +0,0 @@ -package org.apache.archiva.repository.maven; - -import org.apache.archiva.common.filelock.DefaultFileLockManager; -import org.apache.archiva.common.filelock.FileLockManager; -import org.apache.archiva.repository.ReleaseScheme; -import org.apache.archiva.repository.RemoteRepository; -import org.apache.archiva.repository.RepositoryCapabilities; -import org.apache.archiva.repository.RepositoryState; -import org.apache.archiva.repository.RepositoryType; -import org.apache.archiva.repository.StandardCapabilities; -import org.apache.archiva.repository.UnsupportedFeatureException; -import org.apache.archiva.repository.base.remote.AbstractRemoteRepository; -import org.apache.archiva.repository.features.IndexCreationFeature; -import org.apache.archiva.repository.features.RemoteIndexFeature; -import org.apache.archiva.repository.features.RepositoryFeature; -import org.apache.archiva.repository.storage.fs.FilesystemStorage; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import java.io.IOException; -import java.nio.file.Path; -import java.util.Locale; - -/* - * 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. - */ - -/** - * Maven2 remote repository implementation - */ -public class MavenRemoteRepository extends AbstractRemoteRepository - implements RemoteRepository -{ - - Logger log = LoggerFactory.getLogger(MavenRemoteRepository.class); - - final private RemoteIndexFeature remoteIndexFeature = new RemoteIndexFeature(); - final private IndexCreationFeature indexCreationFeature; - - private static final RepositoryCapabilities CAPABILITIES = new StandardCapabilities( - new ReleaseScheme[] { ReleaseScheme.RELEASE, ReleaseScheme.SNAPSHOT }, - new String[] { MavenManagedRepository.DEFAULT_LAYOUT, MavenManagedRepository.LEGACY_LAYOUT}, - new String[] {}, - new String[] {RemoteIndexFeature.class.getName(), IndexCreationFeature.class.getName()}, - true, - true, - true, - true, - false - ); - - public MavenRemoteRepository(String id, String name, FilesystemStorage storage) - { - super( RepositoryType.MAVEN, id, name, storage ); - this.indexCreationFeature = new IndexCreationFeature(this, this); - setLastState( RepositoryState.CREATED ); - } - - public MavenRemoteRepository( Locale primaryLocale, String id, String name, FilesystemStorage storage ) - { - super( primaryLocale, RepositoryType.MAVEN, id, name, storage ); - this.indexCreationFeature = new IndexCreationFeature(this, this); - setLastState( RepositoryState.CREATED ); - } - - @Override - public boolean hasIndex( ) - { - return remoteIndexFeature.hasIndex(); - } - - @Override - public RepositoryCapabilities getCapabilities( ) - { - return CAPABILITIES; - } - - @SuppressWarnings( "unchecked" ) - @Override - public > RepositoryFeature getFeature( Class clazz ) throws UnsupportedFeatureException - { - if (RemoteIndexFeature.class.equals( clazz )) { - return (RepositoryFeature) remoteIndexFeature; - } else if (IndexCreationFeature.class.equals(clazz)) { - return (RepositoryFeature) indexCreationFeature; - } else { - throw new UnsupportedFeatureException( ); - } - } - - @Override - public > boolean supportsFeature( Class clazz ) - { - if ( RemoteIndexFeature.class.equals(clazz) || IndexCreationFeature.class.equals(clazz)) { - return true; - } else { - return false; - } - } - - @Override - public String toString() { - return super.toString()+", remoteIndexFeature="+remoteIndexFeature.toString()+", indexCreationFeature="+indexCreationFeature.toString(); - } - - public static MavenRemoteRepository newLocalInstance(String id, String name, Path basePath) throws IOException { - FileLockManager lockManager = new DefaultFileLockManager(); - FilesystemStorage storage = new FilesystemStorage(basePath.resolve(id), lockManager); - return new MavenRemoteRepository(id, name, storage); - } -} diff --git a/archiva-modules/archiva-maven/archiva-maven-repository/src/main/java/org/apache/archiva/repository/maven/MavenRepositoryGroup.java b/archiva-modules/archiva-maven/archiva-maven-repository/src/main/java/org/apache/archiva/repository/maven/MavenRepositoryGroup.java deleted file mode 100644 index 2bfd34afa..000000000 --- a/archiva-modules/archiva-maven/archiva-maven-repository/src/main/java/org/apache/archiva/repository/maven/MavenRepositoryGroup.java +++ /dev/null @@ -1,86 +0,0 @@ -package org.apache.archiva.repository.maven; - -/* - * 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.filelock.DefaultFileLockManager; -import org.apache.archiva.common.filelock.FileLockManager; -import org.apache.archiva.repository.EditableRepositoryGroup; -import org.apache.archiva.repository.ReleaseScheme; -import org.apache.archiva.repository.RepositoryCapabilities; -import org.apache.archiva.repository.RepositoryState; -import org.apache.archiva.repository.RepositoryType; -import org.apache.archiva.repository.StandardCapabilities; -import org.apache.archiva.repository.base.group.AbstractRepositoryGroup; -import org.apache.archiva.repository.features.IndexCreationFeature; -import org.apache.archiva.repository.storage.fs.FilesystemStorage; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import java.io.IOException; -import java.nio.file.Path; -import java.util.Locale; - -public class MavenRepositoryGroup extends AbstractRepositoryGroup implements EditableRepositoryGroup { - - private static final RepositoryCapabilities CAPABILITIES = new StandardCapabilities( - new ReleaseScheme[] { ReleaseScheme.RELEASE, ReleaseScheme.SNAPSHOT }, - new String[] { MavenManagedRepository.DEFAULT_LAYOUT, MavenManagedRepository.LEGACY_LAYOUT}, - new String[] {}, - new String[] {IndexCreationFeature.class.getName()}, - false, - false, - false, - false, - false - ); - - private final Logger log = LoggerFactory.getLogger(MavenRepositoryGroup.class); - - private IndexCreationFeature indexCreationFeature; - - - public MavenRepositoryGroup(String id, String name, FilesystemStorage storage) { - super(RepositoryType.MAVEN, id, name, storage); - init(); - setLastState( RepositoryState.CREATED ); - } - - public MavenRepositoryGroup(Locale primaryLocale, String id, String name, FilesystemStorage storage) { - super(primaryLocale, RepositoryType.MAVEN, id, name, storage); - init(); - setLastState( RepositoryState.CREATED ); - } - - private Path getRepositoryPath() { - return getStorage().getRoot().getFilePath(); - } - - private void init() { - setCapabilities(CAPABILITIES); - this.indexCreationFeature = new IndexCreationFeature(this, this); - addFeature( this.indexCreationFeature ); - } - - public static MavenRepositoryGroup newLocalInstance(String id, String name, Path basePath) throws IOException { - FileLockManager lockManager = new DefaultFileLockManager(); - FilesystemStorage storage = new FilesystemStorage(basePath.resolve(id), lockManager); - return new MavenRepositoryGroup(id, name, storage); - } -} diff --git a/archiva-modules/archiva-maven/archiva-maven-repository/src/main/java/org/apache/archiva/repository/maven/MavenRepositoryProvider.java b/archiva-modules/archiva-maven/archiva-maven-repository/src/main/java/org/apache/archiva/repository/maven/MavenRepositoryProvider.java deleted file mode 100644 index f5b2b1ec8..000000000 --- a/archiva-modules/archiva-maven/archiva-maven-repository/src/main/java/org/apache/archiva/repository/maven/MavenRepositoryProvider.java +++ /dev/null @@ -1,575 +0,0 @@ -package org.apache.archiva.repository.maven; - -/* - * 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.filelock.FileLockManager; -import org.apache.archiva.configuration.AbstractRepositoryConfiguration; -import org.apache.archiva.configuration.ArchivaConfiguration; -import org.apache.archiva.configuration.ManagedRepositoryConfiguration; -import org.apache.archiva.configuration.RemoteRepositoryConfiguration; -import org.apache.archiva.configuration.RepositoryGroupConfiguration; -import org.apache.archiva.event.Event; -import org.apache.archiva.event.EventHandler; -import org.apache.archiva.repository.EditableManagedRepository; -import org.apache.archiva.repository.EditableRemoteRepository; -import org.apache.archiva.repository.EditableRepository; -import org.apache.archiva.repository.EditableRepositoryGroup; -import org.apache.archiva.repository.ManagedRepository; -import org.apache.archiva.repository.ReleaseScheme; -import org.apache.archiva.repository.RemoteRepository; -import org.apache.archiva.repository.Repository; -import org.apache.archiva.repository.RepositoryCredentials; -import org.apache.archiva.repository.RepositoryException; -import org.apache.archiva.repository.RepositoryGroup; -import org.apache.archiva.repository.RepositoryProvider; -import org.apache.archiva.repository.RepositoryType; -import org.apache.archiva.repository.UnsupportedURIException; -import org.apache.archiva.repository.base.managed.BasicManagedRepository; -import org.apache.archiva.repository.base.PasswordCredentials; -import org.apache.archiva.repository.event.RepositoryEvent; -import org.apache.archiva.repository.features.ArtifactCleanupFeature; -import org.apache.archiva.repository.features.IndexCreationFeature; -import org.apache.archiva.repository.features.RemoteIndexFeature; -import org.apache.archiva.repository.features.StagingRepositoryFeature; -import org.apache.archiva.repository.storage.fs.FilesystemStorage; -import org.apache.commons.lang3.StringUtils; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.stereotype.Service; - -import javax.inject.Inject; -import java.io.IOException; -import java.net.URI; -import java.net.URISyntaxException; -import java.nio.file.Files; -import java.nio.file.Path; -import java.nio.file.Paths; -import java.time.Duration; -import java.time.Period; -import java.time.temporal.ChronoUnit; -import java.util.ArrayList; -import java.util.HashSet; -import java.util.List; -import java.util.Set; -import java.util.stream.Collectors; - -import static org.apache.archiva.indexer.ArchivaIndexManager.DEFAULT_INDEX_PATH; -import static org.apache.archiva.indexer.ArchivaIndexManager.DEFAULT_PACKED_INDEX_PATH; - -/** - * Provider for the maven2 repository implementation - */ -@Service("mavenRepositoryProvider") -public class MavenRepositoryProvider implements RepositoryProvider { - - - @Inject - private ArchivaConfiguration archivaConfiguration; - - @Inject - private FileLockManager fileLockManager; - - private final List> repositoryEventHandlers = new ArrayList<>( ); - - private static final Logger log = LoggerFactory.getLogger(MavenRepositoryProvider.class); - - static final Set TYPES = new HashSet<>(); - - static { - TYPES.add(RepositoryType.MAVEN); - } - - @Override - public Set provides() { - return TYPES; - } - - @Override - public MavenManagedRepository createManagedInstance(String id, String name) { - return createManagedInstance(id, name, archivaConfiguration.getRemoteRepositoryBaseDir()); - } - - public MavenManagedRepository createManagedInstance(String id, String name, Path baseDir) { - FilesystemStorage storage; - try { - storage = new FilesystemStorage(baseDir.resolve(id), fileLockManager); - } catch (IOException e) { - log.error("Could not initialize fileystem for repository {}", id); - throw new RuntimeException(e); - } - MavenManagedRepository repo = new MavenManagedRepository( id, name, storage ); - registerEventHandler( repo ); - return repo; - } - - @Override - public MavenRemoteRepository createRemoteInstance(String id, String name) { - return createRemoteInstance(id, name, archivaConfiguration.getRemoteRepositoryBaseDir()); - } - - public MavenRemoteRepository createRemoteInstance(String id, String name, Path baseDir) { - FilesystemStorage storage; - try { - storage = new FilesystemStorage(baseDir.resolve(id), fileLockManager); - } catch (IOException e) { - log.error("Could not initialize filesystem for repository {}: '{}'", id, e.getMessage()); - throw new RuntimeException(e); - } - MavenRemoteRepository repo = new MavenRemoteRepository( id, name, storage ); - registerEventHandler( repo ); - return repo; - } - - @Override - public EditableRepositoryGroup createRepositoryGroup(String id, String name) { - return createRepositoryGroup(id, name, archivaConfiguration.getRepositoryGroupBaseDir().resolve( id )); - } - - public MavenRepositoryGroup createRepositoryGroup(String id, String name, Path repositoryPath) { - FilesystemStorage storage; - try { - storage = new FilesystemStorage(repositoryPath, fileLockManager); - } catch (IOException e) { - log.error("Could not initialize filesystem for repository {}: '{}'", id, e.getMessage()); - throw new RuntimeException(e); - } - MavenRepositoryGroup group = new MavenRepositoryGroup( id, name, storage ); - registerEventHandler( group ); - return group; - } - - private void registerEventHandler( Repository repo ) { - for (EventHandler eventHandler : repositoryEventHandlers) { - repo.registerEventHandler( RepositoryEvent.ANY, eventHandler ); - } - } - - private URI getURIFromString(String uriStr) throws RepositoryException { - URI uri; - try { - if (StringUtils.isEmpty(uriStr)) { - return new URI(""); - } - if (uriStr.startsWith("/")) { - // only absolute paths are prepended with file scheme - uri = new URI("file://" + uriStr); - } else if (uriStr.contains(":\\")) { - //windows absolute path drive - uri = new URI("file:///" + uriStr.replaceAll("\\\\", "/")); - } else { - uri = new URI(uriStr); - } - if (uri.getScheme() != null && !"file".equals(uri.getScheme())) { - log.error("Bad URI scheme found: {}, URI={}", uri.getScheme(), uri); - throw new RepositoryException("The uri " + uriStr + " is not valid. Only file:// URI is allowed for maven."); - } - } catch (URISyntaxException e) { - String newCfg = "file://" + uriStr; - try { - uri = new URI(newCfg); - } catch (URISyntaxException e1) { - log.error("Could not create URI from {} -> {}", uriStr, newCfg); - throw new RepositoryException("The config entry " + uriStr + " cannot be converted to URI."); - } - } - log.debug("Setting location uri: {}", uri); - return uri; - } - - @Override - public ManagedRepository createManagedInstance(ManagedRepositoryConfiguration cfg) throws RepositoryException { - MavenManagedRepository repo = createManagedInstance(cfg.getId(), cfg.getName(), Paths.get(cfg.getLocation()).getParent()); - updateManagedInstance(repo, cfg); - return repo; - } - - @Override - public void updateManagedInstance(EditableManagedRepository repo, ManagedRepositoryConfiguration cfg) throws RepositoryException { - try { - repo.setLocation(getURIFromString(cfg.getLocation())); - } catch (UnsupportedURIException e) { - throw new RepositoryException("The location entry is not a valid uri: " + cfg.getLocation()); - } - setBaseConfig(repo, cfg); - Path repoDir = repo.getRoot().getFilePath(); - if (!Files.exists(repoDir)) { - log.debug("Creating repo directory {}", repoDir); - try { - Files.createDirectories(repoDir); - } catch (IOException e) { - log.error("Could not create directory {} for repository {}", repoDir, repo.getId(), e); - throw new RepositoryException("Could not create directory for repository " + repoDir); - } - } - repo.setSchedulingDefinition(cfg.getRefreshCronExpression()); - repo.setBlocksRedeployment(cfg.isBlockRedeployments()); - repo.setScanned(cfg.isScanned()); - if (cfg.isReleases()) { - repo.addActiveReleaseScheme(ReleaseScheme.RELEASE); - } else { - repo.removeActiveReleaseScheme(ReleaseScheme.RELEASE); - } - if (cfg.isSnapshots()) { - repo.addActiveReleaseScheme(ReleaseScheme.SNAPSHOT); - } else { - repo.removeActiveReleaseScheme(ReleaseScheme.SNAPSHOT); - } - - StagingRepositoryFeature stagingRepositoryFeature = repo.getFeature(StagingRepositoryFeature.class).get(); - stagingRepositoryFeature.setStageRepoNeeded(cfg.isStageRepoNeeded()); - - IndexCreationFeature indexCreationFeature = repo.getFeature(IndexCreationFeature.class).get(); - indexCreationFeature.setSkipPackedIndexCreation(cfg.isSkipPackedIndexCreation()); - String indexDir = StringUtils.isEmpty( cfg.getIndexDir() ) ? DEFAULT_INDEX_PATH : cfg.getIndexDir(); - String packedIndexDir = StringUtils.isEmpty( cfg.getPackedIndexDir() ) ? DEFAULT_PACKED_INDEX_PATH : cfg.getPackedIndexDir(); - indexCreationFeature.setIndexPath(getURIFromString(indexDir)); - indexCreationFeature.setPackedIndexPath(getURIFromString(packedIndexDir)); - - ArtifactCleanupFeature artifactCleanupFeature = repo.getFeature(ArtifactCleanupFeature.class).get(); - - artifactCleanupFeature.setDeleteReleasedSnapshots(cfg.isDeleteReleasedSnapshots()); - artifactCleanupFeature.setRetentionCount(cfg.getRetentionCount()); - artifactCleanupFeature.setRetentionPeriod(Period.ofDays(cfg.getRetentionPeriod())); - } - - - @Override - public ManagedRepository createStagingInstance(ManagedRepositoryConfiguration baseConfiguration) throws RepositoryException { - log.debug("Creating staging instance for {}", baseConfiguration.getId()); - return createManagedInstance(getStageRepoConfig(baseConfiguration)); - } - - - @Override - public RemoteRepository createRemoteInstance(RemoteRepositoryConfiguration cfg) throws RepositoryException { - MavenRemoteRepository repo = createRemoteInstance(cfg.getId(), cfg.getName(), archivaConfiguration.getRemoteRepositoryBaseDir()); - updateRemoteInstance(repo, cfg); - return repo; - } - - private String convertUriToPath(URI uri) { - if (uri.getScheme() == null) { - return uri.getPath(); - } else if ("file".equals(uri.getScheme())) { - return Paths.get(uri).toString(); - } else { - return uri.toString(); - } - } - - @Override - public void updateRemoteInstance(EditableRemoteRepository repo, RemoteRepositoryConfiguration cfg) throws RepositoryException { - setBaseConfig(repo, cfg); - repo.setCheckPath(cfg.getCheckPath()); - repo.setSchedulingDefinition(cfg.getRefreshCronExpression()); - try { - repo.setLocation(new URI(cfg.getUrl())); - } catch (UnsupportedURIException | URISyntaxException e) { - log.error("Could not set remote url " + cfg.getUrl()); - throw new RepositoryException("The url config is not a valid uri: " + cfg.getUrl()); - } - repo.setTimeout(Duration.ofSeconds(cfg.getTimeout())); - RemoteIndexFeature remoteIndexFeature = repo.getFeature(RemoteIndexFeature.class).get(); - remoteIndexFeature.setDownloadRemoteIndex(cfg.isDownloadRemoteIndex()); - remoteIndexFeature.setDownloadRemoteIndexOnStartup(cfg.isDownloadRemoteIndexOnStartup()); - remoteIndexFeature.setDownloadTimeout(Duration.ofSeconds(cfg.getRemoteDownloadTimeout())); - remoteIndexFeature.setProxyId(cfg.getRemoteDownloadNetworkProxyId()); - if (cfg.isDownloadRemoteIndex()) { - try { - remoteIndexFeature.setIndexUri(new URI(cfg.getRemoteIndexUrl())); - } catch (URISyntaxException e) { - log.error("Could not set remote index url " + cfg.getRemoteIndexUrl()); - remoteIndexFeature.setDownloadRemoteIndex(false); - remoteIndexFeature.setDownloadRemoteIndexOnStartup(false); - } - } - for ( Object key : cfg.getExtraHeaders().keySet() ) { - repo.addExtraHeader( key.toString(), cfg.getExtraHeaders().get(key).toString() ); - } - for ( Object key : cfg.getExtraParameters().keySet() ) { - repo.addExtraParameter( key.toString(), cfg.getExtraParameters().get(key).toString() ); - } - PasswordCredentials credentials = new PasswordCredentials("", new char[0]); - if (cfg.getPassword() != null && cfg.getUsername() != null) { - credentials.setPassword(cfg.getPassword().toCharArray()); - credentials.setUsername(cfg.getUsername()); - repo.setCredentials(credentials); - } else { - credentials.setPassword(new char[0]); - } - IndexCreationFeature indexCreationFeature = repo.getFeature(IndexCreationFeature.class).get(); - if ( !StringUtils.isEmpty( cfg.getIndexDir( ) ) ) - { - indexCreationFeature.setIndexPath( getURIFromString( cfg.getIndexDir( ) ) ); - } - if (!StringUtils.isEmpty( cfg.getPackedIndexDir() )) { - indexCreationFeature.setPackedIndexPath(getURIFromString(cfg.getPackedIndexDir())); - } - log.debug("Updated remote instance {}", repo); - } - - @Override - public RepositoryGroup createRepositoryGroup(RepositoryGroupConfiguration configuration) throws RepositoryException { - Path repositoryPath = getRepositoryGroupPath( configuration ); - MavenRepositoryGroup newGrp = createRepositoryGroup(configuration.getId(), configuration.getName(), - repositoryPath); - updateRepositoryGroupInstance(newGrp, configuration); - return newGrp; - } - - private Path getRepositoryGroupPath(RepositoryGroupConfiguration configuration) { - if (StringUtils.isNotEmpty( configuration.getLocation() )) { - return Paths.get( configuration.getLocation( ) ); - } else { - return getArchivaConfiguration( ).getRepositoryGroupBaseDir( ).resolve( configuration.getId( ) ); - } - } - - @Override - public void updateRepositoryGroupInstance(EditableRepositoryGroup repositoryGroup, RepositoryGroupConfiguration configuration) throws RepositoryException { - repositoryGroup.setName(repositoryGroup.getPrimaryLocale(), configuration.getName()); - repositoryGroup.setMergedIndexTTL(configuration.getMergedIndexTtl()); - repositoryGroup.setSchedulingDefinition(configuration.getCronExpression()); - if (repositoryGroup.supportsFeature( IndexCreationFeature.class )) { - IndexCreationFeature indexCreationFeature = repositoryGroup.getFeature( IndexCreationFeature.class ).get(); - indexCreationFeature.setIndexPath( getURIFromString(configuration.getMergedIndexPath()) ); - Path localPath = Paths.get(configuration.getMergedIndexPath()); - Path repoGroupPath = repositoryGroup.getRoot().getFilePath().toAbsolutePath(); - if (localPath.isAbsolute() && !localPath.startsWith(repoGroupPath)) { - try { - FilesystemStorage storage = new FilesystemStorage(localPath.getParent(), fileLockManager); - indexCreationFeature.setLocalIndexPath(storage.getAsset(localPath.getFileName().toString())); - } catch (IOException e) { - throw new RepositoryException("Could not initialize storage for index path "+localPath); - } - } else if (localPath.isAbsolute()) { - indexCreationFeature.setLocalIndexPath(repositoryGroup.getAsset(repoGroupPath.relativize(localPath).toString())); - } else - { - indexCreationFeature.setLocalIndexPath(repositoryGroup.getAsset(localPath.toString())); - } - } - // References to other repositories are set filled by the registry - } - - @Override - public RemoteRepositoryConfiguration getRemoteConfiguration(RemoteRepository remoteRepository) throws RepositoryException { - if (!(remoteRepository instanceof MavenRemoteRepository)) { - log.error("Wrong remote repository type " + remoteRepository.getClass().getName()); - throw new RepositoryException("The given repository type cannot be handled by the maven provider: " + remoteRepository.getClass().getName()); - } - RemoteRepositoryConfiguration cfg = new RemoteRepositoryConfiguration(); - cfg.setType(remoteRepository.getType().toString()); - cfg.setId(remoteRepository.getId()); - cfg.setName(remoteRepository.getName()); - cfg.setDescription(remoteRepository.getDescription()); - cfg.setUrl(remoteRepository.getLocation().toString()); - cfg.setTimeout((int) remoteRepository.getTimeout().toMillis() / 1000); - cfg.setCheckPath(remoteRepository.getCheckPath()); - RepositoryCredentials creds = remoteRepository.getLoginCredentials(); - if (creds != null) { - if (creds instanceof PasswordCredentials) { - PasswordCredentials pCreds = (PasswordCredentials) creds; - cfg.setPassword(new String(pCreds.getPassword())); - cfg.setUsername(pCreds.getUsername()); - } - } - cfg.setLayout(remoteRepository.getLayout()); - cfg.setExtraParameters(remoteRepository.getExtraParameters()); - cfg.setExtraHeaders(remoteRepository.getExtraHeaders()); - cfg.setRefreshCronExpression(remoteRepository.getSchedulingDefinition()); - - IndexCreationFeature indexCreationFeature = remoteRepository.getFeature(IndexCreationFeature.class).get(); - cfg.setIndexDir(convertUriToPath(indexCreationFeature.getIndexPath())); - cfg.setPackedIndexDir(convertUriToPath(indexCreationFeature.getPackedIndexPath())); - - RemoteIndexFeature remoteIndexFeature = remoteRepository.getFeature(RemoteIndexFeature.class).get(); - if ( remoteIndexFeature.getIndexUri( ) == null ) - { - cfg.setRemoteIndexUrl( "" ); - } - else - { - cfg.setRemoteIndexUrl(remoteIndexFeature.getIndexUri().toString()); - } - cfg.setRemoteDownloadTimeout((int) remoteIndexFeature.getDownloadTimeout().get(ChronoUnit.SECONDS)); - cfg.setDownloadRemoteIndexOnStartup(remoteIndexFeature.isDownloadRemoteIndexOnStartup()); - cfg.setDownloadRemoteIndex(remoteIndexFeature.isDownloadRemoteIndex()); - cfg.setRemoteDownloadNetworkProxyId(remoteIndexFeature.getProxyId()); - if ( StringUtils.isEmpty( remoteIndexFeature.getProxyId( ) ) ) - { - cfg.setRemoteDownloadNetworkProxyId(""); - } - else - { - cfg.setRemoteDownloadNetworkProxyId(remoteIndexFeature.getProxyId()); - } - - - return cfg; - - } - - @Override - public ManagedRepositoryConfiguration getManagedConfiguration(ManagedRepository managedRepository) throws RepositoryException { - if (!(managedRepository instanceof MavenManagedRepository || managedRepository instanceof BasicManagedRepository )) { - log.error("Wrong remote repository type " + managedRepository.getClass().getName()); - throw new RepositoryException("The given repository type cannot be handled by the maven provider: " + managedRepository.getClass().getName()); - } - ManagedRepositoryConfiguration cfg = new ManagedRepositoryConfiguration(); - cfg.setType(managedRepository.getType().toString()); - cfg.setId(managedRepository.getId()); - cfg.setName(managedRepository.getName()); - cfg.setDescription(managedRepository.getDescription()); - cfg.setLocation(convertUriToPath(managedRepository.getLocation())); - cfg.setLayout(managedRepository.getLayout()); - cfg.setRefreshCronExpression(managedRepository.getSchedulingDefinition()); - cfg.setScanned(managedRepository.isScanned()); - cfg.setBlockRedeployments(managedRepository.blocksRedeployments()); - StagingRepositoryFeature stagingRepositoryFeature = managedRepository.getFeature(StagingRepositoryFeature.class).get(); - cfg.setStageRepoNeeded(stagingRepositoryFeature.isStageRepoNeeded()); - IndexCreationFeature indexCreationFeature = managedRepository.getFeature(IndexCreationFeature.class).get(); - cfg.setIndexDir(convertUriToPath(indexCreationFeature.getIndexPath())); - cfg.setPackedIndexDir(convertUriToPath(indexCreationFeature.getPackedIndexPath())); - cfg.setSkipPackedIndexCreation(indexCreationFeature.isSkipPackedIndexCreation()); - - ArtifactCleanupFeature artifactCleanupFeature = managedRepository.getFeature(ArtifactCleanupFeature.class).get(); - cfg.setRetentionCount(artifactCleanupFeature.getRetentionCount()); - cfg.setRetentionPeriod(artifactCleanupFeature.getRetentionPeriod().getDays()); - cfg.setDeleteReleasedSnapshots(artifactCleanupFeature.isDeleteReleasedSnapshots()); - - cfg.setReleases( managedRepository.getActiveReleaseSchemes( ).contains( ReleaseScheme.RELEASE ) ); - cfg.setSnapshots( managedRepository.getActiveReleaseSchemes( ).contains( ReleaseScheme.SNAPSHOT ) ); - return cfg; - - } - - @Override - public RepositoryGroupConfiguration getRepositoryGroupConfiguration(RepositoryGroup repositoryGroup) throws RepositoryException { - if (repositoryGroup.getType() != RepositoryType.MAVEN) { - throw new RepositoryException("The given repository group is not of MAVEN type"); - } - RepositoryGroupConfiguration cfg = new RepositoryGroupConfiguration(); - cfg.setId(repositoryGroup.getId()); - cfg.setName(repositoryGroup.getName()); - if (repositoryGroup.supportsFeature( IndexCreationFeature.class )) - { - IndexCreationFeature indexCreationFeature = repositoryGroup.getFeature( IndexCreationFeature.class ).get(); - - cfg.setMergedIndexPath( indexCreationFeature.getIndexPath().toString() ); - } - cfg.setMergedIndexTtl(repositoryGroup.getMergedIndexTTL()); - cfg.setRepositories(repositoryGroup.getRepositories().stream().map( Repository::getId ).collect(Collectors.toList())); - cfg.setCronExpression(repositoryGroup.getSchedulingDefinition()); - return cfg; - } - - @Override - public void addRepositoryEventHandler( EventHandler eventHandler ) - { - this.repositoryEventHandlers.add( eventHandler ); - } - - private ManagedRepositoryConfiguration getStageRepoConfig(ManagedRepositoryConfiguration repository) { - ManagedRepositoryConfiguration stagingRepository = new ManagedRepositoryConfiguration(); - stagingRepository.setId(repository.getId() + StagingRepositoryFeature.STAGING_REPO_POSTFIX); - stagingRepository.setLayout(repository.getLayout()); - stagingRepository.setName(repository.getName() + StagingRepositoryFeature.STAGING_REPO_POSTFIX); - stagingRepository.setBlockRedeployments(repository.isBlockRedeployments()); - stagingRepository.setRetentionPeriod(repository.getRetentionPeriod()); - stagingRepository.setDeleteReleasedSnapshots(repository.isDeleteReleasedSnapshots()); - stagingRepository.setStageRepoNeeded(false); - - String path = repository.getLocation(); - int lastIndex = path.replace('\\', '/').lastIndexOf('/'); - stagingRepository.setLocation(path.substring(0, lastIndex) + "/" + stagingRepository.getId()); - - if (StringUtils.isNotBlank(repository.getIndexDir())) { - Path indexDir; - try { - if (repository.getIndexDir().startsWith( "file:" )) { - indexDir = Paths.get( new URI( repository.getIndexDir( ) ) ); - } else - { - indexDir = Paths.get( repository.getIndexDir( ) ); - } - if (indexDir.isAbsolute()) { - Path newDir = indexDir.getParent().resolve(indexDir.getFileName() + StagingRepositoryFeature.STAGING_REPO_POSTFIX); - log.debug("Changing index directory {} -> {}", indexDir, newDir); - stagingRepository.setIndexDir(newDir.toString()); - } else { - log.debug("Keeping index directory {}", repository.getIndexDir()); - stagingRepository.setIndexDir(repository.getIndexDir()); - } - } catch (URISyntaxException e) { - log.error("Could not parse index path as uri {}", repository.getIndexDir()); - stagingRepository.setIndexDir(""); - } - // in case of absolute dir do not use the same - } - if (StringUtils.isNotBlank(repository.getPackedIndexDir())) { - Path packedIndexDir; - packedIndexDir = Paths.get(repository.getPackedIndexDir()); - if (packedIndexDir.isAbsolute()) { - Path newDir = packedIndexDir.getParent().resolve(packedIndexDir.getFileName() + StagingRepositoryFeature.STAGING_REPO_POSTFIX); - log.debug("Changing index directory {} -> {}", packedIndexDir, newDir); - stagingRepository.setPackedIndexDir(newDir.toString()); - } else { - log.debug("Keeping index directory {}", repository.getPackedIndexDir()); - stagingRepository.setPackedIndexDir(repository.getPackedIndexDir()); - } - // in case of absolute dir do not use the same - } - stagingRepository.setRefreshCronExpression(repository.getRefreshCronExpression()); - stagingRepository.setReleases(repository.isReleases()); - stagingRepository.setRetentionCount(repository.getRetentionCount()); - stagingRepository.setScanned(repository.isScanned()); - stagingRepository.setSnapshots(repository.isSnapshots()); - stagingRepository.setSkipPackedIndexCreation(repository.isSkipPackedIndexCreation()); - // do not duplicate description - //stagingRepository.getDescription("") - return stagingRepository; - } - - private void setBaseConfig( EditableRepository repo, AbstractRepositoryConfiguration cfg) - { - - URI baseUri = archivaConfiguration.getRepositoryBaseDir().toUri(); - repo.setBaseUri(baseUri); - - repo.setName(repo.getPrimaryLocale(), cfg.getName()); - repo.setDescription(repo.getPrimaryLocale(), cfg.getDescription()); - repo.setLayout(cfg.getLayout()); - } - - public ArchivaConfiguration getArchivaConfiguration() { - return archivaConfiguration; - } - - public void setArchivaConfiguration(ArchivaConfiguration archivaConfiguration) { - this.archivaConfiguration = archivaConfiguration; - } - - @Override - public void handle(Event event) { - // - } - -} diff --git a/archiva-modules/archiva-maven/archiva-maven-repository/src/main/java/org/apache/archiva/repository/maven/MavenSystemManager.java b/archiva-modules/archiva-maven/archiva-maven-repository/src/main/java/org/apache/archiva/repository/maven/MavenSystemManager.java deleted file mode 100644 index 76d47cdde..000000000 --- a/archiva-modules/archiva-maven/archiva-maven-repository/src/main/java/org/apache/archiva/repository/maven/MavenSystemManager.java +++ /dev/null @@ -1,119 +0,0 @@ -package org.apache.archiva.repository.maven; - -/* - * 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.repository.maven.dependency.tree.ArchivaRepositoryConnectorFactory; -import org.apache.maven.repository.internal.DefaultArtifactDescriptorReader; -import org.apache.maven.repository.internal.DefaultVersionRangeResolver; -import org.apache.maven.repository.internal.DefaultVersionResolver; -import org.apache.maven.repository.internal.MavenRepositorySystemUtils; -import org.eclipse.aether.DefaultRepositorySystemSession; -import org.eclipse.aether.RepositorySystem; -import org.eclipse.aether.RepositorySystemSession; -import org.eclipse.aether.collection.DependencySelector; -import org.eclipse.aether.impl.ArtifactDescriptorReader; -import org.eclipse.aether.impl.DefaultServiceLocator; -import org.eclipse.aether.impl.VersionRangeResolver; -import org.eclipse.aether.impl.VersionResolver; -import org.eclipse.aether.internal.impl.SimpleLocalRepositoryManagerFactory; -import org.eclipse.aether.repository.LocalRepository; -import org.eclipse.aether.repository.LocalRepositoryManager; -import org.eclipse.aether.repository.NoLocalRepositoryManagerException; -import org.eclipse.aether.spi.connector.RepositoryConnectorFactory; -import org.eclipse.aether.util.graph.selector.AndDependencySelector; -import org.eclipse.aether.util.graph.selector.ExclusionDependencySelector; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.stereotype.Service; - -import javax.annotation.PostConstruct; - -/** - * Some static utility methods that are used by different classes. - */ -@Service("mavenSystemManager") -public class MavenSystemManager { - - static Logger log = LoggerFactory.getLogger(MavenSystemManager.class); - - private DefaultServiceLocator locator; - private RepositorySystem system; - - @PostConstruct - private synchronized void init() { - locator = newLocator(); - system = newRepositorySystem(locator); - - } - - /** - * Creates a new aether repository system session for the given directory and assigns the - * repository to this session. - * - * @param localRepoDir The repository directory - * @return The newly created session object. - */ - public static RepositorySystemSession newRepositorySystemSession(String localRepoDir) { - DefaultRepositorySystemSession session = MavenRepositorySystemUtils.newSession(); - - LocalRepository repo = new LocalRepository(localRepoDir); - - DependencySelector depFilter = new AndDependencySelector(new ExclusionDependencySelector()); - session.setDependencySelector(depFilter); - SimpleLocalRepositoryManagerFactory repFactory = new SimpleLocalRepositoryManagerFactory(); - try { - LocalRepositoryManager manager = repFactory.newInstance(session, repo); - session.setLocalRepositoryManager(manager); - } catch (NoLocalRepositoryManagerException e) { - log.error("Could not assign the repository manager to the session: {}", e.getMessage(), e); - } - - return session; - } - - public RepositorySystem getRepositorySystem() { - return system; - } - - public DefaultServiceLocator getLocator() { - return locator; - } - - /** - * Finds the - * - * @return - */ - public static RepositorySystem newRepositorySystem(DefaultServiceLocator locator) { - return locator.getService(RepositorySystem.class); - } - - public static DefaultServiceLocator newLocator() { - DefaultServiceLocator locator = MavenRepositorySystemUtils.newServiceLocator(); - - locator.addService(RepositoryConnectorFactory.class, - ArchivaRepositoryConnectorFactory.class);// FileRepositoryConnectorFactory.class ); - locator.addService(VersionResolver.class, DefaultVersionResolver.class); - locator.addService(VersionRangeResolver.class, DefaultVersionRangeResolver.class); - locator.addService(ArtifactDescriptorReader.class, DefaultArtifactDescriptorReader.class); - - return locator; - } -} diff --git a/archiva-modules/archiva-maven/archiva-maven-repository/src/main/java/org/apache/archiva/repository/maven/content/AbstractDefaultRepositoryContent.java b/archiva-modules/archiva-maven/archiva-maven-repository/src/main/java/org/apache/archiva/repository/maven/content/AbstractDefaultRepositoryContent.java deleted file mode 100644 index 79ecfaf89..000000000 --- a/archiva-modules/archiva-maven/archiva-maven-repository/src/main/java/org/apache/archiva/repository/maven/content/AbstractDefaultRepositoryContent.java +++ /dev/null @@ -1,364 +0,0 @@ -package org.apache.archiva.repository.maven.content; - -/* - * 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.utils.VersionUtil; -import org.apache.archiva.metadata.repository.storage.RepositoryPathTranslator; -import org.apache.archiva.repository.RepositoryContent; -import org.apache.archiva.repository.content.ItemSelector; -import org.apache.archiva.repository.content.LayoutException; -import org.apache.archiva.repository.content.base.ArchivaItemSelector; -import org.apache.archiva.repository.maven.metadata.storage.ArtifactMappingProvider; -import org.apache.commons.lang3.StringUtils; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import java.util.List; -import java.util.regex.Matcher; -import java.util.regex.Pattern; - -/** - * AbstractDefaultRepositoryContent - common methods for working with default (maven 2) layout. - */ -public abstract class AbstractDefaultRepositoryContent implements RepositoryContent -{ - - - protected Logger log = LoggerFactory.getLogger( getClass() ); - - public static final String MAVEN_METADATA = "maven-metadata.xml"; - - protected static final char PATH_SEPARATOR = '/'; - - protected static final char GROUP_SEPARATOR = '.'; - - protected static final char ARTIFACT_SEPARATOR = '-'; - - private static final Pattern TIMESTAMP_PATTERN = Pattern.compile( "([0-9]{8}.[0-9]{6})-([0-9]+).*" ); - private static final Pattern MAVEN_PLUGIN_PATTERN = Pattern.compile( "^(maven-.*-plugin)|(.*-maven-plugin)$" ); - - private RepositoryPathTranslator pathTranslator; - private List artifactMappingProviders; - - - AbstractDefaultRepositoryContent() { - } - - public RepositoryPathTranslator getPathTranslator( ) - { - return pathTranslator; - } - - public void setPathTranslator( RepositoryPathTranslator pathTranslator ) - { - this.pathTranslator = pathTranslator; - } - - public void setArtifactMappingProviders(List artifactMappingProviders) { - this.artifactMappingProviders = artifactMappingProviders; - } - - public ArchivaItemSelector.Builder getArtifactFromFilename( String namespace, String projectId, String projectVersion, - String artifactFileName ) - { - if ( !artifactFileName.startsWith( projectId + "-" ) ) - { - throw new IllegalArgumentException( "Not a valid artifact path in a Maven 2 repository, filename '" + artifactFileName - + "' doesn't start with artifact ID '" + projectId + "'" ); - } - - int index = projectId.length() + 1; - String version; - String idSubStrFromVersion = artifactFileName.substring( index ); - if ( idSubStrFromVersion.startsWith( projectVersion ) && !VersionUtil.isUniqueSnapshot( projectVersion ) ) - { - // non-snapshot versions, or non-timestamped snapshot versions - version = projectVersion; - } - else if ( VersionUtil.isGenericSnapshot( projectVersion ) ) - { - // timestamped snapshots - try - { - int mainVersionLength = projectVersion.length() - 8; // 8 is length of "SNAPSHOT" - if ( mainVersionLength == 0 ) - { - throw new IllegalArgumentException( - "Timestamped snapshots must contain the main version, filename was '" + artifactFileName + "'" ); - } - - Matcher m = TIMESTAMP_PATTERN.matcher( idSubStrFromVersion.substring( mainVersionLength ) ); - m.matches(); - String timestamp = m.group( 1 ); - String buildNumber = m.group( 2 ); - version = idSubStrFromVersion.substring( 0, mainVersionLength ) + timestamp + "-" + buildNumber; - } - catch ( IllegalStateException e ) - { - throw new IllegalArgumentException( "Not a valid artifact path in a Maven 2 repository, filename '" + artifactFileName - + "' doesn't contain a timestamped version matching snapshot '" - + projectVersion + "'", e); - } - } - else - { - // invalid - throw new IllegalArgumentException( - "Not a valid artifact path in a Maven 2 repository, filename '" + artifactFileName + "' doesn't contain version '" - + projectVersion + "'" ); - } - - String classifier; - String ext; - index += version.length(); - if ( index == artifactFileName.length() ) - { - // no classifier or extension - classifier = null; - ext = null; - } - else - { - char c = artifactFileName.charAt( index ); - if ( c == '-' ) - { - // classifier up until '.' - int extIndex = artifactFileName.indexOf( '.', index ); - if ( extIndex >= 0 ) - { - classifier = artifactFileName.substring( index + 1, extIndex ); - ext = artifactFileName.substring( extIndex + 1 ); - } - else - { - classifier = artifactFileName.substring( index + 1 ); - ext = null; - } - } - else if ( c == '.' ) - { - // rest is the extension - classifier = null; - ext = artifactFileName.substring( index + 1 ); - } - else - { - throw new IllegalArgumentException( "Not a valid artifact path in a Maven 2 repository, filename '" + artifactFileName - + "' expected classifier or extension but got '" - + artifactFileName.substring( index ) + "'" ); - } - } - - ArchivaItemSelector.Builder selectorBuilder = ArchivaItemSelector.builder( ) - .withNamespace( namespace ) - .withProjectId( projectId ) - .withArtifactId( projectId ) - .withVersion( projectVersion ) - .withArtifactVersion( version ) - .withClassifier( classifier ); - - - // we use our own provider here instead of directly accessing Maven's artifact handlers as it has no way - // to select the correct order to apply multiple extensions mappings to a preferred type - // TODO: this won't allow the user to decide order to apply them if there are conflicts or desired changes - - // perhaps the plugins could register missing entries in configuration, then we just use configuration - // here? - - String type = null; - for ( ArtifactMappingProvider mapping : artifactMappingProviders ) - { - type = mapping.mapClassifierAndExtensionToType( classifier, ext ); - if ( type != null ) - { - break; - } - } - - // TODO: this is cheating! We should check the POM metadata instead - if ( type == null && "jar".equals( ext ) && isArtifactIdValidMavenPlugin( projectId ) ) - { - type = "maven-plugin"; - } - - // use extension as default - if ( type == null ) - { - type = ext; - } - - // TODO: should we allow this instead? - if ( type == null ) - { - throw new IllegalArgumentException( - "Not a valid artifact path in a Maven 2 repository, filename '" + artifactFileName + "' does not have a type" ); - } - - selectorBuilder.withType( type ); - - - return selectorBuilder; - } - - public boolean isArtifactIdValidMavenPlugin( String artifactId ) - { - return MAVEN_PLUGIN_PATTERN.matcher( artifactId ).matches(); - } - - private ArchivaItemSelector getArtifactForPath( String relativePath ) - { - String[] parts = relativePath.replace( '\\', '/' ).split( "/" ); - - int len = parts.length; - if ( len < 4 ) - { - throw new IllegalArgumentException( - "Not a valid artifact path in a Maven 2 repository, not enough directories: " + relativePath ); - } - - String fileName = parts[--len]; - String baseVersion = parts[--len]; - String artifactId = parts[--len]; - StringBuilder namespaceBuilder = new StringBuilder(); - for ( int i = 0; i < len - 1; i++ ) - { - namespaceBuilder.append( parts[i] ); - namespaceBuilder.append( '.' ); - } - namespaceBuilder.append( parts[len - 1] ); - - return getArtifactFromFilename( namespaceBuilder.toString(), artifactId, baseVersion, fileName ).build(); - } - - @Override - public ItemSelector toItemSelector( String path ) throws LayoutException - { - if ( StringUtils.isBlank( path ) ) - { - throw new LayoutException( "Unable to convert blank path." ); - } - try - { - - return getArtifactForPath( path ); - } - catch ( IllegalArgumentException e ) - { - throw new LayoutException( e.getMessage(), e ); - } - - } - - @Override - public String toPath ( ItemSelector selector ) { - if (selector==null) { - throw new IllegalArgumentException( "ItemSelector must not be null." ); - } - String projectId; - // Initialize the project id if not set - if (selector.hasProjectId()) { - projectId = selector.getProjectId( ); - } else if (selector.hasArtifactId()) { - // projectId same as artifact id, if set - projectId = selector.getArtifactId( ); - } else { - // we arrive here, if projectId && artifactId not set - return pathTranslator.toPath( selector.getNamespace(), ""); - } - if ( !selector.hasArtifactId( )) { - return pathTranslator.toPath( selector.getNamespace( ), projectId ); - } - // this part only, if projectId && artifactId is set - String artifactVersion = ""; - String version = ""; - if (selector.hasVersion() && selector.hasArtifactVersion() ) { - artifactVersion = selector.getArtifactVersion(); - version = VersionUtil.getBaseVersion( selector.getVersion( ) ); - } else if (!selector.hasVersion() && selector.hasArtifactVersion()) { - // we try to retrieve the base version, if artifact version is only set - version = VersionUtil.getBaseVersion( selector.getArtifactVersion( ) ); - artifactVersion = selector.getArtifactVersion( ); - } else if (selector.hasVersion() && !selector.hasArtifactVersion()) { - artifactVersion = selector.getVersion(); - version = VersionUtil.getBaseVersion( selector.getVersion( ) ); - } - - return pathTranslator.toPath( selector.getNamespace(), projectId, version, - constructId( selector.getArtifactId(), artifactVersion, selector.getClassifier(), selector.getType() ) ); - - } - - - public String toPath( String namespace ) - { - return formatAsDirectory( namespace ); - } - - - protected String formatAsDirectory( String directory ) - { - return directory.replace( GROUP_SEPARATOR, PATH_SEPARATOR ); - } - - private String toPath( String groupId, String artifactId, String baseVersion, String version, String classifier, - String type ) - { - if ( baseVersion != null ) - { - return pathTranslator.toPath( groupId, artifactId, baseVersion, - constructId( artifactId, version, classifier, type ) ); - } - else - { - return pathTranslator.toPath( groupId, artifactId ); - } - } - - // TODO: move into the Maven Artifact facet when refactoring away the caller - the caller will need to have access - // to the facet or filename (for the original ID) - private String constructId( String artifactId, String version, String classifier, String type ) - { - String ext = null; - for ( ArtifactMappingProvider provider : artifactMappingProviders ) - { - ext = provider.mapTypeToExtension( type ); - if ( ext != null ) - { - break; - } - } - if ( ext == null ) - { - ext = type; - } - - StringBuilder id = new StringBuilder(); - if ( ( version != null ) && ( type != null ) ) - { - id.append( artifactId ).append( ARTIFACT_SEPARATOR ).append( version ); - - if ( StringUtils.isNotBlank( classifier ) ) - { - id.append( ARTIFACT_SEPARATOR ).append( classifier ); - } - - id.append( "." ).append( ext ); - } - return id.toString(); - } -} diff --git a/archiva-modules/archiva-maven/archiva-maven-repository/src/main/java/org/apache/archiva/repository/maven/content/ArtifactExtensionMapping.java b/archiva-modules/archiva-maven/archiva-maven-repository/src/main/java/org/apache/archiva/repository/maven/content/ArtifactExtensionMapping.java deleted file mode 100644 index 2b73aa27f..000000000 --- a/archiva-modules/archiva-maven/archiva-maven-repository/src/main/java/org/apache/archiva/repository/maven/content/ArtifactExtensionMapping.java +++ /dev/null @@ -1,77 +0,0 @@ -package org.apache.archiva.repository.maven.content; - -/* - * 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.repository.maven.metadata.storage.ArtifactMappingProvider; -import org.apache.archiva.repository.maven.metadata.storage.DefaultArtifactMappingProvider; - -/** - * ArtifactExtensionMapping - * - * - */ -public class ArtifactExtensionMapping -{ - public static final String MAVEN_ONE_PLUGIN = "maven-one-plugin"; - - // TODO: now only used in Maven 1, we should be using M1 specific mappings - private static final ArtifactMappingProvider mapping = new DefaultArtifactMappingProvider(); - - public static String getExtension( String type ) - { - String ext = mapping.mapTypeToExtension( type ); - - if ( ext == null ) - { - ext = type; - } - - return ext; - } - - public static String mapExtensionAndClassifierToType( String classifier, String extension ) - { - return mapExtensionAndClassifierToType( classifier, extension, extension ); - } - - public static String mapExtensionAndClassifierToType( String classifier, String extension, - String defaultExtension ) - { - String value = mapping.mapClassifierAndExtensionToType( classifier, extension ); - if ( value == null ) - { - // TODO: Maven 1 plugin - String value1 = null; - if ( "tar.gz".equals( extension ) ) - { - value1 = "distribution-tgz"; - } - else if ( "tar.bz2".equals( extension ) ) - { - value1 = "distribution-bzip"; - } - else if ( "zip".equals( extension ) ) - { - value1 = "distribution-zip"; - } - value = value1; - } - return value != null ? value : defaultExtension; - } -} diff --git a/archiva-modules/archiva-maven/archiva-maven-repository/src/main/java/org/apache/archiva/repository/maven/content/ArtifactInfo.java b/archiva-modules/archiva-maven/archiva-maven-repository/src/main/java/org/apache/archiva/repository/maven/content/ArtifactInfo.java deleted file mode 100644 index 3a198cc8b..000000000 --- a/archiva-modules/archiva-maven/archiva-maven-repository/src/main/java/org/apache/archiva/repository/maven/content/ArtifactInfo.java +++ /dev/null @@ -1,42 +0,0 @@ -package org.apache.archiva.repository.maven.content; - -/* - * 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.repository.content.ArtifactType; -import org.apache.archiva.repository.content.BaseArtifactTypes; -import org.apache.archiva.repository.storage.StorageAsset; - -/** - * @author Martin Stockhammer - */ // Simple object to hold artifact information -class ArtifactInfo -{ - protected String id; - protected String version; - protected String extension; - protected String remainder; - protected String type; - protected String classifier; - protected String contentType; - protected String namespace; - protected String project; - protected String projectVersion; - protected StorageAsset asset; - protected ArtifactType artifactType = BaseArtifactTypes.MAIN; -} diff --git a/archiva-modules/archiva-maven/archiva-maven-repository/src/main/java/org/apache/archiva/repository/maven/content/FilenameParser.java b/archiva-modules/archiva-maven/archiva-maven-repository/src/main/java/org/apache/archiva/repository/maven/content/FilenameParser.java deleted file mode 100644 index 31b2fe1fc..000000000 --- a/archiva-modules/archiva-maven/archiva-maven-repository/src/main/java/org/apache/archiva/repository/maven/content/FilenameParser.java +++ /dev/null @@ -1,258 +0,0 @@ -package org.apache.archiva.repository.maven.content; - -/* - * 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.utils.VersionUtil; - -import java.util.regex.Matcher; -import java.util.regex.Pattern; - -/** - * Generic Filename Parser for use with layout routines. - * - * - */ -public class FilenameParser -{ - private String name; - - private String extension; - - private int offset; - - private static final Pattern mavenPluginPattern = Pattern.compile( "(maven-.*-plugin)|(.*-maven-plugin)" ); - - private static final Pattern extensionPattern = - Pattern.compile( "(\\.tar\\.gz$)|(\\.tar\\.bz2$)|(\\.[\\-a-z0-9]*$)", Pattern.CASE_INSENSITIVE ); - - private static final Pattern SNAPSHOT_PATTERN = Pattern.compile( "^([0-9]{8}\\.[0-9]{6}-[0-9]+)(.*)$" ); - - private static final Pattern section = Pattern.compile( "([^-]*)" ); - - private Matcher matcher; - - public FilenameParser( String filename ) - { - this.name = filename; - - Matcher mat = extensionPattern.matcher( name ); - if ( mat.find() ) - { - extension = filename.substring( mat.start() + 1 ); - name = name.substring( 0, name.length() - extension.length() - 1 ); - } - - matcher = section.matcher( name ); - - reset(); - } - - public void reset() - { - offset = 0; - } - - public String next() - { - // Past the end of the string. - if ( offset > name.length() ) - { - return null; - } - - // Return the next section. - if ( matcher.find( offset ) ) - { - // Return found section. - offset = matcher.end() + 1; - return matcher.group(); - } - - // Nothing to return. - return null; - } - - protected String expect( String expected ) - { - String value = null; - - if ( name.startsWith( expected, offset ) ) - { - value = expected; - } - else if ( VersionUtil.isGenericSnapshot( expected ) ) - { - String version = name.substring( offset ); - - // check it starts with the same version up to the snapshot part - int leadingLength = expected.length() - 9; - if ( leadingLength > 0 && version.startsWith( expected.substring( 0, leadingLength ) ) && - version.length() > leadingLength ) - { - // If we expect a non-generic snapshot - look for the timestamp - Matcher m = SNAPSHOT_PATTERN.matcher( version.substring( leadingLength + 1 ) ); - if ( m.matches() ) - { - value = version.substring( 0, leadingLength + 1 ) + m.group( 1 ); - } - } - } - - if ( value != null ) - { - // Potential hit. check for '.' or '-' at end of expected. - int seperatorOffset = offset + value.length(); - - // Test for "out of bounds" first. - if ( seperatorOffset >= name.length() ) - { - offset = name.length(); - return value; - } - - // Test for seperator char. - char seperatorChar = name.charAt( seperatorOffset ); - if ( ( seperatorChar == '-' ) || ( seperatorChar == '.' ) ) - { - offset = seperatorOffset + 1; - return value; - } - } - - return null; - } - - /** - * Get the current seperator character. - * - * @return the seperator character (either '.' or '-'), or 0 if no seperator character available. - */ - protected char seperator() - { - // Past the end of the string? - if ( offset >= name.length() ) - { - return 0; - } - - // Before the start of the string? - if ( offset <= 0 ) - { - return 0; - } - - return name.charAt( offset - 1 ); - } - - protected String getName() - { - return name; - } - - public String getExtension() - { - return extension; - } - - public String remaining() - { - if ( offset >= name.length() ) - { - return null; - } - - String end = name.substring( offset ); - offset = name.length(); - return end; - } - - public String nextNonVersion() - { - boolean done = false; - - StringBuilder ver = new StringBuilder(); - - // Any text upto the end of a special case is considered non-version. - Matcher specialMat = mavenPluginPattern.matcher( name ); - if ( specialMat.find() ) - { - ver.append( name.substring( offset, specialMat.end() ) ); - offset = specialMat.end() + 1; - } - - while ( !done ) - { - int initialOffset = offset; - String section = next(); - if ( section == null ) - { - done = true; - } - else if ( !VersionUtil.isVersion( section ) ) - { - if ( ver.length() > 0 ) - { - ver.append( '-' ); - } - ver.append( section ); - } - else - { - offset = initialOffset; - done = true; - } - } - - return ver.toString(); - } - - protected String nextVersion() - { - boolean done = false; - - StringBuilder ver = new StringBuilder(); - - while ( !done ) - { - int initialOffset = offset; - String section = next(); - if ( section == null ) - { - done = true; - } - else if ( VersionUtil.isVersion( section ) ) - { - if ( ver.length() > 0 ) - { - ver.append( '-' ); - } - ver.append( section ); - } - else - { - offset = initialOffset; - done = true; - } - } - - return ver.toString(); - } - - -} diff --git a/archiva-modules/archiva-maven/archiva-maven-repository/src/main/java/org/apache/archiva/repository/maven/content/ManagedDefaultRepositoryContent.java b/archiva-modules/archiva-maven/archiva-maven-repository/src/main/java/org/apache/archiva/repository/maven/content/ManagedDefaultRepositoryContent.java deleted file mode 100644 index 88711a58f..000000000 --- a/archiva-modules/archiva-maven/archiva-maven-repository/src/main/java/org/apache/archiva/repository/maven/content/ManagedDefaultRepositoryContent.java +++ /dev/null @@ -1,1610 +0,0 @@ -package org.apache.archiva.repository.maven.content; - -/* - * 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.filelock.FileLockManager; -import org.apache.archiva.common.utils.FileUtils; -import org.apache.archiva.common.utils.VersionUtil; -import org.apache.archiva.configuration.FileTypes; -import org.apache.archiva.maven.metadata.MavenMetadataReader; -import org.apache.archiva.repository.EditableManagedRepository; -import org.apache.archiva.repository.ItemDeleteStatus; -import org.apache.archiva.repository.ManagedRepository; -import org.apache.archiva.repository.ManagedRepositoryContent; -import org.apache.archiva.repository.content.Artifact; -import org.apache.archiva.repository.content.BaseArtifactTypes; -import org.apache.archiva.repository.content.BaseRepositoryContentLayout; -import org.apache.archiva.repository.content.ContentAccessException; -import org.apache.archiva.repository.content.ContentItem; -import org.apache.archiva.repository.content.DataItem; -import org.apache.archiva.repository.content.ItemNotFoundException; -import org.apache.archiva.repository.content.ItemSelector; -import org.apache.archiva.repository.content.LayoutException; -import org.apache.archiva.repository.content.LayoutRuntimeException; -import org.apache.archiva.repository.content.ManagedRepositoryContentLayout; -import org.apache.archiva.repository.content.Namespace; -import org.apache.archiva.repository.content.Project; -import org.apache.archiva.repository.content.Version; -import org.apache.archiva.repository.content.base.ArchivaContentItem; -import org.apache.archiva.repository.content.base.ArchivaItemSelector; -import org.apache.archiva.repository.content.base.ArchivaNamespace; -import org.apache.archiva.repository.content.base.ArchivaProject; -import org.apache.archiva.repository.content.base.ArchivaVersion; -import org.apache.archiva.repository.content.base.builder.ArtifactOptBuilder; -import org.apache.archiva.repository.storage.RepositoryStorage; -import org.apache.archiva.repository.storage.StorageAsset; -import org.apache.archiva.repository.storage.util.StorageUtil; -import org.apache.commons.collections4.map.ReferenceMap; -import org.apache.commons.lang3.StringUtils; - -import javax.inject.Inject; -import javax.inject.Named; -import java.io.IOException; -import java.nio.file.Files; -import java.nio.file.Path; -import java.util.Arrays; -import java.util.Collections; -import java.util.List; -import java.util.Objects; -import java.util.Optional; -import java.util.function.Consumer; -import java.util.function.Predicate; -import java.util.regex.Matcher; -import java.util.regex.Pattern; -import java.util.stream.Collectors; -import java.util.stream.Stream; - -/** - * ManagedDefaultRepositoryContent - */ -public class ManagedDefaultRepositoryContent - extends AbstractDefaultRepositoryContent - implements ManagedRepositoryContent, BaseRepositoryContentLayout -{ - - // attribute flag that marks version objects that point to a snapshot artifact version - public static final String SNAPSHOT_ARTIFACT_VERSION = "maven.snav"; - - private FileTypes filetypes; - - public void setFileTypes( FileTypes fileTypes ) - { - this.filetypes = fileTypes; - } - - private ManagedRepository repository; - - private FileLockManager lockManager; - - @Inject - @Named( "metadataReader#maven" ) - MavenMetadataReader metadataReader; - - @Inject - @Named( "MavenContentHelper" ) - MavenContentHelper mavenContentHelper; - - public static final String SNAPSHOT = "SNAPSHOT"; - - public static final Pattern UNIQUE_SNAPSHOT_PATTERN = Pattern.compile( "^(SNAPSHOT|[0-9]{8}\\.[0-9]{6}-[0-9]+)(.*)" ); - public static final Pattern CLASSIFIER_PATTERN = Pattern.compile( "^-([^.]+)(\\..*)" ); - public static final Pattern COMMON_EXTENSIONS = Pattern.compile( "^(jar|war|ear|dar|tar|zip|pom|xml)$" ); - - public static final Pattern TIMESTAMP_PATTERN = Pattern.compile( "^([0-9]{8})\\.([0-9]{6})$" ); - - public static final Pattern GENERIC_SNAPSHOT_PATTERN = Pattern.compile( "^(.*)-" + SNAPSHOT ); - - private static final List> LAYOUTS = Arrays.asList( BaseRepositoryContentLayout.class ); - - /** - * We are caching content items in a weak reference map. To avoid always recreating the - * the hierarchical structure. - * TODO: Better use a object cache? E.g. our spring cache implementation? - */ - private ReferenceMap itemMap = new ReferenceMap<>( ); - private ReferenceMap dataItemMap = new ReferenceMap<>( ); - - public ManagedDefaultRepositoryContent( ) - { - super( ); - } - - public ManagedDefaultRepositoryContent( ManagedRepository repository, FileTypes fileTypes, FileLockManager lockManager ) - { - super( ); - setFileTypes( fileTypes ); - this.lockManager = lockManager; - setRepository( repository ); - } - - private StorageAsset getAssetByPath( String assetPath ) - { - return getStorage( ).getAsset( assetPath ); - } - - private StorageAsset getAsset( String namespace ) - { - String namespacePath = formatAsDirectory( namespace.trim( ) ); - if ( StringUtils.isEmpty( namespacePath ) ) - { - namespacePath = ""; - } - return getAssetByPath( namespacePath ); - } - - private StorageAsset getAsset( String namespace, String project ) - { - return getAsset( namespace ).resolve( project ); - } - - private StorageAsset getAsset( String namespace, String project, String version ) - { - return getAsset( namespace, project ).resolve( version ); - } - - private StorageAsset getAsset( String namespace, String project, String version, String fileName ) - { - return getAsset( namespace, project, version ).resolve( fileName ); - } - - - /// ************* Start of new generation interface ****************** - - - @Override - public T adaptItem( Class clazz, ContentItem item ) throws LayoutException - { - try - { - if ( clazz.isAssignableFrom( Version.class ) ) - { - if ( !item.hasCharacteristic( Version.class ) ) - { - item.setCharacteristic( Version.class, createVersionFromPath( item.getAsset( ) ) ); - } - return (T) item.adapt( Version.class ); - } - else if ( clazz.isAssignableFrom( Project.class ) ) - { - if ( !item.hasCharacteristic( Project.class ) ) - { - item.setCharacteristic( Project.class, createProjectFromPath( item.getAsset( ) ) ); - } - return (T) item.adapt( Project.class ); - } - else if ( clazz.isAssignableFrom( Namespace.class ) ) - { - if ( !item.hasCharacteristic( Namespace.class ) ) - { - item.setCharacteristic( Namespace.class, createNamespaceFromPath( item.getAsset( ) ) ); - } - return (T) item.adapt( Namespace.class ); - } - else if ( clazz.isAssignableFrom( Artifact.class ) ) - { - if ( !item.hasCharacteristic( Artifact.class ) ) - { - item.setCharacteristic( Artifact.class, createArtifactFromPath( item.getAsset( ) ) ); - } - return (T) item.adapt( Artifact.class ); - } - } catch (LayoutRuntimeException e) { - throw new LayoutException( e.getMessage( ), e ); - } - throw new LayoutException( "Could not convert item to class " + clazz); - } - - - @Override - public void deleteAllItems( ItemSelector selector, Consumer consumer ) throws ContentAccessException, IllegalArgumentException - { - try ( Stream stream = newItemStream( selector, false ) ) - { - stream.forEach( item -> { - try - { - deleteItem( item ); - consumer.accept( new ItemDeleteStatus( item ) ); - } - catch ( ItemNotFoundException e ) - { - consumer.accept( new ItemDeleteStatus( item, ItemDeleteStatus.ITEM_NOT_FOUND, e ) ); - } - catch ( Exception e ) - { - consumer.accept( new ItemDeleteStatus( item, ItemDeleteStatus.DELETION_FAILED, e ) ); - } - catch ( Throwable e ) - { - consumer.accept( new ItemDeleteStatus( item, ItemDeleteStatus.UNKNOWN, e ) ); - } - } ); - } - } - - /** - * Removes the item from the filesystem. For namespaces, projects and versions it deletes - * recursively. - * For namespaces you have to be careful, because maven repositories may have sub namespaces - * parallel to projects. Which means deleting a namespaces also deletes the sub namespaces and - * not only the projects of the given namespace. Better run the delete for each project of - * a namespace. - *

- * Artifacts are deleted as provided. No related artifacts will be deleted. - * - * @param item the item that should be removed - * @throws ItemNotFoundException if the item does not exist - * @throws ContentAccessException if some error occurred while accessing the filesystem - */ - @Override - public void deleteItem( ContentItem item ) throws ItemNotFoundException, ContentAccessException - { - final Path baseDirectory = getRepoDir( ); - final Path itemPath = item.getAsset( ).getFilePath( ); - if ( !Files.exists( itemPath ) ) - { - throw new ItemNotFoundException( "The item " + item.toString( ) + "does not exist in the repository " + getId( ) ); - } - if ( !itemPath.toAbsolutePath( ).startsWith( baseDirectory.toAbsolutePath( ) ) ) - { - log.error( "The namespace {} to delete from repository {} is not a subdirectory of the repository base.", item, getId( ) ); - log.error( "Namespace directory: {}", itemPath ); - log.error( "Repository directory: {}", baseDirectory ); - throw new ContentAccessException( "Inconsistent directories found. Could not delete namespace." ); - } - try - { - if ( Files.isDirectory( itemPath ) ) - { - FileUtils.deleteDirectory( itemPath ); - } - else - { - Files.deleteIfExists( itemPath ); - } - } - catch ( IOException e ) - { - log.error( "Could not delete item from path {}: {}", itemPath, e.getMessage( ), e ); - throw new ContentAccessException( "Error occured while deleting item " + item + ": " + e.getMessage( ), e ); - } - } - - @Override - public void copyItem( ContentItem item, ManagedRepository destinationRepository ) throws ItemNotFoundException, ContentAccessException - { - - } - - @Override - public void copyItem( ContentItem item, ManagedRepository destinationRepository, boolean updateMetadata ) throws ItemNotFoundException, ContentAccessException - { - - } - - @Override - public ContentItem getItem( ItemSelector selector ) throws ContentAccessException, IllegalArgumentException - { - if ( selector.hasVersion( ) && selector.hasArtifactId( ) ) - { - return getArtifact( selector ); - } else if ( !selector.hasVersion() && selector.hasArtifactVersion() && selector.hasArtifactId() ) { - String baseVersion = VersionUtil.getBaseVersion( selector.getArtifactVersion( ) ); - ItemSelector selector1 = ArchivaItemSelector.builder( ).withSelector( selector ) - .withVersion(baseVersion).build(); - return getArtifact( selector1 ); - } - else if ( selector.hasProjectId( ) && selector.hasVersion( ) ) - { - return getVersion( selector ); - } - else if ( selector.hasProjectId( ) ) - { - return getProject( selector ); - } - else - { - return getNamespace( selector ); - } - } - - @Override - public Namespace getNamespace( final ItemSelector namespaceSelector ) throws ContentAccessException, IllegalArgumentException - { - StorageAsset nsPath = getAsset( namespaceSelector.getNamespace() ); - try - { - return getNamespaceFromPath( nsPath ); - } - catch ( LayoutException e ) - { - throw new IllegalArgumentException( "Not a valid selector " + e.getMessage( ), e ); - } - } - - - @Override - public Project getProject( final ItemSelector selector ) throws ContentAccessException, IllegalArgumentException - { - if ( !selector.hasProjectId( ) ) - { - throw new IllegalArgumentException( "Project id must be set" ); - } - final StorageAsset path = getAsset( selector.getNamespace( ), selector.getProjectId( ) ); - try - { - return getProjectFromPath( path ); - } - catch ( LayoutException e ) - { - throw new IllegalArgumentException( "Not a valid selector " + e.getMessage( ), e ); - } - } - - - @Override - public Version getVersion( final ItemSelector selector ) throws ContentAccessException, IllegalArgumentException - { - if ( !selector.hasProjectId( ) ) - { - throw new IllegalArgumentException( "Project id must be set" ); - } - if ( !selector.hasVersion( ) ) - { - throw new IllegalArgumentException( "Version must be set" ); - } - final StorageAsset path = getAsset( selector.getNamespace( ), selector.getProjectId( ), selector.getVersion( ) ); - try - { - return getVersionFromPath( path ); - } - catch ( LayoutException e ) - { - throw new IllegalArgumentException( "Not a valid selector " + e.getMessage( ), e ); - } - } - - - public Artifact createArtifact( final StorageAsset artifactPath, final ItemSelector selector, - final String classifier ) - { - Version version = getVersion( selector ); - ArtifactOptBuilder builder = org.apache.archiva.repository.content.base.ArchivaArtifact.withAsset( artifactPath ) - .withVersion( version ) - .withId( selector.getArtifactId( ) ) - .withArtifactVersion( mavenContentHelper.getArtifactVersion( artifactPath, selector ) ) - .withClassifier( classifier ); - if ( selector.hasType( ) ) - { - builder.withType( selector.getType( ) ); - } - return builder.build( ); - } - - public Namespace getNamespaceFromArtifactPath( final StorageAsset artifactPath ) throws LayoutException - { - if (artifactPath == null) { - throw new LayoutException( "Path null is not valid for artifact" ); - } - final StorageAsset namespacePath = artifactPath.getParent( ).getParent( ).getParent( ); - return getNamespaceFromPath( namespacePath ); - } - - public Namespace getNamespaceFromPath( final StorageAsset nsPath ) throws LayoutException - { - if (nsPath == null) { - throw new LayoutException( "Path null is not valid for namespace" ); - } - - ContentItem item; - try - { - item = itemMap.computeIfAbsent( nsPath, - path -> createNamespaceFromPath( nsPath ) ); - } - catch ( LayoutRuntimeException e ) - { - throw new LayoutException( e.getMessage( ), e.getCause() ); - } - if (!item.hasCharacteristic( Namespace.class )) { - item.setCharacteristic( Namespace.class, createNamespaceFromPath( nsPath ) ); - } - return item.adapt( Namespace.class ); - } - - public Namespace createNamespaceFromPath( final StorageAsset namespacePath) throws LayoutRuntimeException - { - if (namespacePath == null) { - throw new LayoutRuntimeException( "Path null is not valid for namespace" ); - } - final String namespace = MavenContentHelper.getNamespaceFromNamespacePath( namespacePath ); - return ArchivaNamespace.withRepository( this ) - .withAsset( namespacePath ) - .withNamespace( namespace ) - .build( ); - } - - private Project getProjectFromPath( final StorageAsset path ) throws LayoutException - { - if (path == null) { - throw new LayoutException( "Path null is not valid for project" ); - } - ContentItem item; - try - { - item = itemMap.computeIfAbsent( path, this::createProjectFromPath ); - } - catch ( LayoutRuntimeException e ) - { - throw new LayoutException( e.getMessage( ), e.getCause( ) ); - } - if (!item.hasCharacteristic( Project.class )) { - item.setCharacteristic( Project.class, createProjectFromPath( path ) ); - } - return item.adapt( Project.class ); - } - - private Project createProjectFromPath( final StorageAsset projectPath ) throws LayoutRuntimeException - { - if (projectPath==null) { - throw new LayoutRuntimeException( "Path null is not valid for project" ); - } - Namespace namespace; - try - { - namespace = getNamespaceFromPath( projectPath.getParent( ) ); - } - catch ( LayoutException e ) - { - throw new LayoutRuntimeException( e.getMessage( ), e.getCause() ); - } - return ArchivaProject.withRepository( this ).withAsset( projectPath ) - .withNamespace( namespace ) - .withId( projectPath.getName( ) ).build( ); - } - - private Project getProjectFromArtifactPath( final StorageAsset artifactPath ) throws LayoutException - { - if (artifactPath == null) { - throw new LayoutException( "Path null is not valid for artifact" ); - } - final StorageAsset projectPath = artifactPath.getParent( ).getParent( ); - return getProjectFromPath( projectPath ); - } - - private Version getVersionFromArtifactPath( final StorageAsset artifactPath ) throws LayoutException - { - if (artifactPath==null) { - throw new LayoutException( "Path null is not valid for version" ); - } - final StorageAsset versionPath = artifactPath.getParent( ); - return getVersionFromPath( versionPath ); - } - - private Version getVersionFromPath( StorageAsset path ) throws LayoutException - { - if (path==null) { - throw new LayoutException( "Path null is not valid for version" ); - } - ContentItem item; - try - { - item = itemMap.computeIfAbsent( path, this::createVersionFromPath ); - } - catch ( LayoutRuntimeException e ) - { - throw new LayoutException( e.getMessage( ), e.getCause( ) ); - } - if (!item.hasCharacteristic( Version.class )) { - item.setCharacteristic( Version.class, createVersionFromPath( path ) ); - } - return item.adapt( Version.class ); - } - - private Version createVersionFromPath(StorageAsset path) throws LayoutRuntimeException - { - if (path==null) { - throw new LayoutRuntimeException( "Path null is not valid for version" ); - } - Project proj; - try - { - proj = getProjectFromPath( path.getParent( ) ); - } - catch ( LayoutException e ) - { - throw new LayoutRuntimeException( e.getMessage( ), e ); - } - return ArchivaVersion.withRepository( this ).withAsset( path ) - .withProject( proj ).withVersion(path.getName()).build(); - } - - private Optional getOptionalArtifactFromPath( final StorageAsset artifactPath) { - try - { - return Optional.of( getArtifactFromPath( artifactPath ) ); - } - catch ( LayoutException e ) - { - log.error( "Could not get artifact from path {}", artifactPath.getPath( ) ); - return Optional.empty( ); - } - } - - private Artifact getArtifactFromPath( final StorageAsset artifactPath ) throws LayoutException - { - if (artifactPath==null) { - throw new LayoutException( "Path null is not valid for artifact" ); - } - DataItem item; - try - { - item = dataItemMap.computeIfAbsent( artifactPath, this::createArtifactFromPath ); - } - catch ( LayoutRuntimeException e ) - { - throw new LayoutException( e.getMessage( ), e.getCause() ); - } - if (!item.hasCharacteristic( Artifact.class )) { - item.setCharacteristic( Artifact.class, createArtifactFromPath( artifactPath ) ); - } - return item.adapt( Artifact.class ); - } - - private Artifact createArtifactFromPath( final StorageAsset artifactPath ) throws LayoutRuntimeException - { - if (artifactPath==null) { - throw new LayoutRuntimeException( "Path null is not valid for artifact" ); - } - final Version version; - try - { - version = getVersionFromArtifactPath( artifactPath ); - } - catch ( LayoutException e ) - { - throw new LayoutRuntimeException( e.getMessage( ), e ); - } - final ArtifactInfo info = getArtifactInfoFromPath( version.getId( ), artifactPath ); - return org.apache.archiva.repository.content.base.ArchivaArtifact.withAsset( artifactPath ) - .withVersion( version ) - .withId( info.id ) - .withClassifier( info.classifier ) - .withRemainder( info.remainder ) - .withType( info.type ) - .withArtifactVersion( info.version ) - .withContentType( info.contentType ) - .withArtifactType( info.artifactType ) - .build( ); - } - - private String getContentType(StorageAsset artifactPath) { - try - { - return Files.probeContentType( artifactPath.getFilePath( ) ); - - } - catch ( IOException e ) - { - return ""; - } - } - - - private DataItem getDataItemFromPath( final StorageAsset artifactPath ) - { - final String contentType = getContentType( artifactPath ); - return dataItemMap.computeIfAbsent( artifactPath, myArtifactPath -> - org.apache.archiva.repository.content.base.ArchivaDataItem.withAsset( artifactPath ) - .withId( artifactPath.getName( ) ) - .withContentType( contentType ) - .build( ) - ); - - } - - private ContentItem getItemFromPath( final StorageAsset itemPath ) - { - if ( itemPath.isLeaf( ) ) - { - if (dataItemMap.containsKey( itemPath )) { - return dataItemMap.get( itemPath ); - } - return getDataItemFromPath( itemPath ); - } - else - { - if (itemMap.containsKey( itemPath )) { - return itemMap.get( itemPath ); - } else { - return ArchivaContentItem.withRepository( this ).withAsset( itemPath ).build(); - } - } - } - - @Override - public ManagedRepositoryContent getGenericContent( ) - { - return this; - } - - private ArtifactInfo getArtifactInfoFromPath( final String genericVersion, final StorageAsset path ) - { - final ArtifactInfo info = new ArtifactInfo( ); - info.asset = path; - info.id = path.getParent( ).getParent( ).getName( ); - final String fileName = path.getName( ); - if ( VersionUtil.isGenericSnapshot( genericVersion ) ) - { - String baseVersion = StringUtils.substringBeforeLast( genericVersion, "-" + SNAPSHOT ); - String prefix = info.id + "-" + baseVersion + "-"; - if ( fileName.startsWith( prefix ) ) - { - String versionPostfix = StringUtils.removeStart( fileName, prefix ); - Matcher matcher = UNIQUE_SNAPSHOT_PATTERN.matcher( versionPostfix ); - if ( matcher.matches( ) ) - { - info.version = baseVersion + "-" + matcher.group( 1 ); - String newPrefix = info.id + "-" + info.version; - if ( fileName.startsWith( newPrefix ) ) - { - String classPostfix = StringUtils.removeStart( fileName, newPrefix ); - Matcher cMatch = CLASSIFIER_PATTERN.matcher( classPostfix ); - if ( cMatch.matches( ) ) - { - info.classifier = cMatch.group( 1 ); - info.remainder = cMatch.group( 2 ); - } - else - { - info.classifier = ""; - info.remainder = classPostfix; - } - } - else - { - log.debug( "Artifact does not match the maven name pattern {}", path ); - info.artifactType = BaseArtifactTypes.UNKNOWN; - info.classifier = ""; - info.remainder = StringUtils.substringAfter( fileName, prefix ); - } - } - else - { - log.debug( "Artifact does not match the snapshot version pattern {}", path ); - - info.artifactType = BaseArtifactTypes.UNKNOWN; - // This is just a guess. No guarantee to the get a usable version. - info.version = StringUtils.removeStart( fileName, info.id + '-' ); - String postfix = StringUtils.substringAfterLast( info.version, "." ).toLowerCase( ); - while ( COMMON_EXTENSIONS.matcher( postfix ).matches( ) ) - { - info.version = StringUtils.substringBeforeLast( info.version, "." ); - postfix = StringUtils.substringAfterLast( info.version, "." ).toLowerCase( ); - } - info.classifier = ""; - info.remainder = StringUtils.substringAfter( fileName, prefix ); - } - } - else - { - log.debug( "Artifact does not match the maven name pattern: {}", path ); - if ( fileName.contains( "-" + baseVersion ) ) - { - info.id = StringUtils.substringBefore( fileName, "-" + baseVersion ); - } - else - { - info.id = fileName; - } - info.artifactType = BaseArtifactTypes.UNKNOWN; - info.version = ""; - info.classifier = ""; - info.remainder = StringUtils.substringAfterLast( fileName, "." ); - } - } - else - { - String prefix = info.id + "-" + genericVersion; - if ( fileName.startsWith( prefix + "-") ) - { - info.version = genericVersion; - String classPostfix = StringUtils.removeStart( fileName, prefix ); - Matcher cMatch = CLASSIFIER_PATTERN.matcher( classPostfix ); - if ( cMatch.matches( ) ) - { - info.classifier = cMatch.group( 1 ); - info.remainder = cMatch.group( 2 ); - } - else - { - info.classifier = ""; - info.remainder = classPostfix; - } - } else if (fileName.startsWith(prefix + ".")) { - info.version = genericVersion; - info.remainder = StringUtils.removeStart( fileName, prefix ); - info.classifier = ""; - } else if (fileName.startsWith(info.id+"-")) { - String postFix = StringUtils.removeStart( fileName, info.id + "-" ); - String versionPart = StringUtils.substringBefore( postFix, "." ); - if (VersionUtil.isVersion(versionPart)) { - info.version = versionPart; - info.remainder = StringUtils.removeStart( postFix, versionPart ); - info.classifier = ""; - } else { - info.version = ""; - info.classifier = ""; - int dotPos = fileName.indexOf( "." ); - info.remainder = fileName.substring( dotPos ); - } - - } - else - { - if ( fileName.contains( "-" + genericVersion ) ) - { - info.id = StringUtils.substringBefore( fileName, "-" + genericVersion ); - } - else - { - info.id = fileName; - info.version = ""; - } - log.debug( "Artifact does not match the version pattern {}", path ); - info.artifactType = BaseArtifactTypes.UNKNOWN; - info.classifier = ""; - info.remainder = StringUtils.substringAfterLast( fileName, "." ); - } - } - info.extension = StringUtils.substringAfterLast( fileName, "." ); - info.type = MavenContentHelper.getTypeFromClassifierAndExtension( info.classifier, info.extension ); - try - { - info.contentType = Files.probeContentType( path.getFilePath( ) ); - } - catch ( IOException e ) - { - info.contentType = ""; - // - } - if ( MavenContentHelper.METADATA_FILENAME.equalsIgnoreCase( fileName ) ) - { - info.artifactType = BaseArtifactTypes.METADATA; - } - else if ( MavenContentHelper.METADATA_REPOSITORY_FILENAME.equalsIgnoreCase( fileName ) ) - { - info.artifactType = MavenTypes.REPOSITORY_METADATA; - } - else if ( StringUtils.isNotEmpty( info.remainder ) && StringUtils.countMatches( info.remainder, "." ) >= 2 ) - { - String mainFile = StringUtils.substringBeforeLast( fileName, "." ); - if ( path.getParent( ).resolve( mainFile ).exists( ) ) - { - info.artifactType = BaseArtifactTypes.RELATED; - } - } - return info; - - } - - @Override - public Artifact getArtifact( final ItemSelector selectorArg ) throws ContentAccessException - { - ItemSelector selector = selectorArg; - if ( !selectorArg.hasProjectId( ) ) - { - throw new IllegalArgumentException( "Project id must be set" ); - } - if ( !selectorArg.hasVersion( ) ) - { - if (selectorArg.hasArtifactVersion() && VersionUtil.isSnapshot( selectorArg.getArtifactVersion() )) { - selector = ArchivaItemSelector.builder( ).withSelector( selectorArg ) - .withVersion( VersionUtil.getBaseVersion( selectorArg.getArtifactVersion( ) ) ).build(); - } else if (selectorArg.hasArtifactVersion()) { - selector = ArchivaItemSelector.builder( ).withSelector( selectorArg ) - .withVersion( selectorArg.getArtifactVersion( ) ).build(); - - } else - { - throw new IllegalArgumentException( "Version must be set" ); - } - } - if ( !selectorArg.hasArtifactId( ) ) - { - throw new IllegalArgumentException( "Artifact id must be set" ); - } - final StorageAsset artifactDir = getAsset( selector.getNamespace( ), selector.getProjectId( ), - selector.getVersion( ) ); - final String artifactVersion = mavenContentHelper.getArtifactVersion( artifactDir, selector ); - final String classifier = MavenContentHelper.getClassifier( selector ); - final String extension = MavenContentHelper.getArtifactExtension( selector ); - final String artifactId = StringUtils.isEmpty( selector.getArtifactId( ) ) ? selector.getProjectId( ) : selector.getArtifactId( ); - final String fileName = MavenContentHelper.getArtifactFileName( artifactId, artifactVersion, classifier, extension ); - final StorageAsset path = getAsset( selector.getNamespace( ), selector.getProjectId( ), - selector.getVersion( ), fileName ); - try - { - return getArtifactFromPath( path ); - } - catch ( LayoutException e ) - { - throw new IllegalArgumentException( "The selector is not valid " + e.getMessage( ), e ); - } - } - - @Override - public Artifact getArtifact( String path ) throws LayoutException, ContentAccessException - { - StorageAsset asset = getAssetByPath( path ); - return getArtifactFromPath( asset ); - } - - /** - * Returns all the subdirectories of the given namespace directory as project. - */ - @Override - public List getProjects( Namespace namespace ) - { - return namespace.getAsset( ).list( ).stream( ) - .filter( StorageAsset::isContainer ) - .map( a -> { - try - { - return getProjectFromPath( a ); - } - catch ( LayoutException e ) - { - log.error( "Not a valid project path " + a.getPath( ), e ); - return null; - } - } ) - .filter( Objects::nonNull ) - .collect( Collectors.toList( ) ); - } - - @Override - public List getProjects( ItemSelector selector ) throws ContentAccessException, IllegalArgumentException - { - return getProjects( getNamespace( selector ) ); - } - - /** - * Returns a version object for each directory that is a direct child of the project directory. - * - * @param project the project for which the versions should be returned - * @return the list of versions or a empty list, if not version was found - */ - @Override - public List getVersions( final Project project ) - { - StorageAsset asset = getAsset( project.getNamespace( ).getId( ), project.getId( ) ); - return asset.list( ).stream( ).filter( StorageAsset::isContainer ) - .map( a -> ArchivaVersion.withAsset( a ) - .withProject( project ) - .withVersion( a.getName( ) ).build( ) ) - .collect( Collectors.toList( ) ); - } - - /** - * Returns the versions that can be found for the given selector. - * - * @param selector the item selector. At least namespace and projectId must be set. - * @return the list of version objects or a empty list, if the selector does not match a version - * @throws ContentAccessException if the access to the underlying backend failed - * @throws IllegalArgumentException if the selector has no projectId specified - */ - @Override - public List getVersions( final ItemSelector selector ) throws ContentAccessException, IllegalArgumentException - { - if ( !selector.hasProjectId( ) ) - { - log.error( "Bad item selector for version list: {}", selector ); - throw new IllegalArgumentException( "Project id not set, while retrieving versions." ); - } - final Project project = getProject( selector ); - if ( selector.hasVersion( ) ) - { - final StorageAsset asset = getAsset( selector.getNamespace( ), selector.getProjectId( ), selector.getVersion( ) ); - return asset.list( ).stream( ).map( a -> getArtifactInfoFromPath( selector.getVersion( ), a ) ) - .filter( ai -> StringUtils.isNotEmpty( ai.version ) ) - .map( v -> { - try - { - return getVersionFromArtifactPath( v.asset ); - } - catch ( LayoutException e ) - { - log.error( "Could not get version from asset " + v.asset.getPath( ) ); - return null; - } - } ) - .filter( Objects::nonNull ) - .distinct( ) - .collect( Collectors.toList( ) ); - } - else - { - return getVersions( project ); - } - } - - public List getArtifactVersions( final ItemSelector selector ) throws ContentAccessException, IllegalArgumentException - { - if ( !selector.hasProjectId( ) ) - { - log.error( "Bad item selector for version list: {}", selector ); - throw new IllegalArgumentException( "Project id not set, while retrieving versions." ); - } - final Project project = getProject( selector ); - if ( selector.hasVersion( ) ) - { - final StorageAsset asset = getAsset( selector.getNamespace( ), selector.getProjectId( ), selector.getVersion( ) ); - return asset.list( ).stream( ).map( a -> getArtifactInfoFromPath( selector.getVersion( ), a ) ) - .filter( ai -> StringUtils.isNotEmpty( ai.version ) ) - .map( v -> v.version ) - .distinct( ) - .collect( Collectors.toList( ) ); - } - else - { - return project.getAsset( ).list( ).stream( ).map( a -> { - try - { - return getVersionFromPath( a ); - } - catch ( LayoutException e ) - { - log.error( "Could not get version from path " + a.getPath( ) ); - return null; - } - } ).filter( Objects::nonNull ) - .flatMap( v -> v.getAsset( ).list( ).stream( ).map( a -> getArtifactInfoFromPath( v.getId( ), a ) ) ) - .filter( ai -> StringUtils.isNotEmpty( ai.version ) ) - .map( v -> v.version ) - .distinct( ) - .collect( Collectors.toList( ) ); - } - } - - - /** - * See {@link #newArtifactStream(ItemSelector)}. This method collects the stream into a list. - * - * @param selector the selector for the artifacts - * @return the list of artifacts - * @throws ContentAccessException if the access to the underlying filesystem failed - */ - @Override - public List getArtifacts( ItemSelector selector ) throws ContentAccessException - { - try ( Stream stream = newArtifactStream( selector ) ) - { - return stream.collect( Collectors.toList( ) ); - } - } - - - /* - * File filter to select certain artifacts using the selector data. - */ - private Predicate getArtifactFileFilterFromSelector( final ItemSelector selector ) - { - Predicate p = StorageAsset::isLeaf; - StringBuilder fileNamePattern = new StringBuilder( "^" ); - if ( selector.hasArtifactId( ) ) - { - fileNamePattern.append( Pattern.quote( selector.getArtifactId( ) ) ).append( "-" ); - } - else - { - fileNamePattern.append( "[A-Za-z0-9_\\-.]+-" ); - } - if ( selector.hasArtifactVersion( ) ) - { - if ( selector.getArtifactVersion( ).contains( "*" ) ) - { - String[] tokens = StringUtils.splitByWholeSeparator( selector.getArtifactVersion( ), "*" ); - for ( String currentToken : tokens ) - { - if ( !currentToken.equals( "" ) ) - { - fileNamePattern.append( Pattern.quote( currentToken ) ); - } - fileNamePattern.append( "[A-Za-z0-9_\\-.]*" ); - } - } - else - { - fileNamePattern.append( Pattern.quote( selector.getArtifactVersion( ) ) ); - } - } - else - { - fileNamePattern.append( "[A-Za-z0-9_\\-.]+" ); - } - String classifier = selector.hasClassifier( ) ? selector.getClassifier( ) : - ( selector.hasType( ) ? MavenContentHelper.getClassifierFromType( selector.getType( ) ) : null ); - if ( classifier != null ) - { - if ( "*".equals( classifier ) ) - { - fileNamePattern.append( "(-[A-Za-z0-9]+)?\\." ); - } - else - { - fileNamePattern.append( "-" ).append( Pattern.quote( classifier ) ).append( "\\." ); - } - } - else - { - fileNamePattern.append( "\\." ); - } - String extension = selector.hasExtension( ) ? selector.getExtension( ) : - ( selector.hasType( ) ? MavenContentHelper.getArtifactExtension( selector ) : null ); - if ( extension != null ) - { - if ( selector.includeRelatedArtifacts( ) ) - { - fileNamePattern.append( Pattern.quote( extension ) ).append( "(\\.[A-Za-z0-9]+)?" ); - } - else - { - fileNamePattern.append( Pattern.quote( extension ) ); - } - } - else - { - fileNamePattern.append( "[A-Za-z0-9.]+" ); - } - final Pattern pattern = Pattern.compile( fileNamePattern.toString( ) ); - return p.and( a -> pattern.matcher( a.getName( ) ).matches( ) ); - } - - - /** - * Returns the artifacts. The number of artifacts returned depend on the selector. - * If the selector sets the flag {@link ItemSelector#includeRelatedArtifacts()} to true, - * additional to the matching artifacts, related artifacts like hash values or signatures are included in the artifact - * stream. - * If the selector sets the flag {@link ItemSelector#recurse()} to true, artifacts of the given - * namespace and from all sub namespaces that start with the given namespace are returned. - *

    - *
  • If only a namespace is given, all artifacts with the given namespace or starting with the given - * namespace (see {@link ItemSelector#recurse()} are returned.
  • - *
  • If a namespace and a project id, or artifact id is given, the artifacts of all versions of the given - * namespace and project are returned.
  • - *
  • If a namespace and a project id or artifact id and a version is given, the artifacts of the given - * version are returned
  • - *
  • If no artifact version or artifact id is given, it will return all "artifacts" found in the directory. - * To select only artifacts that match the layout you should add the artifact id and artifact version - * (can contain a '*' pattern).
  • - *
- *

- * The '*' pattern can be used in classifiers and artifact versions and match zero or more characters. - *

- * There is no determinate order of the elements in the stream. - *

- * Returned streams are auto closable and should be used in a try-with-resources statement. - * - * @param selector the item selector - * @throws ContentAccessException if the access to the underlying filesystem failed - */ - @Override - public Stream newArtifactStream( ItemSelector selector ) throws ContentAccessException - { - String projectId = selector.hasProjectId( ) ? selector.getProjectId( ) : ( selector.hasArtifactId( ) ? selector.getArtifactId( ) - : null ); - final Predicate filter = getArtifactFileFilterFromSelector( selector ); - if ( projectId != null && selector.hasVersion( ) ) - { - return getAsset( selector.getNamespace( ), projectId, selector.getVersion( ) ) - .list( ).stream( ).filter( filter ) - .map( this::getOptionalArtifactFromPath ) - .filter( Optional::isPresent ).map( Optional::get ); - } - else if ( projectId != null ) - { - final StorageAsset projDir = getAsset( selector.getNamespace( ), projectId ); - return projDir.list( ).stream( ) - .map( a -> a.isContainer( ) ? a.list( ) : Collections.singletonList( a ) ) - .flatMap( List::stream ) - .filter( filter ) - .map( this::getOptionalArtifactFromPath ) - .filter( Optional::isPresent ).map( Optional::get ); - } - else - { - StorageAsset namespaceDir = getAsset( selector.getNamespace( ) ); - if ( selector.recurse( ) ) - { - return StorageUtil.newAssetStream( namespaceDir, true ) - .filter( filter ) - .map( this::getOptionalArtifactFromPath ) - .filter( Optional::isPresent ).map( Optional::get ); - } - else - { - // We descend into 2 subdirectories (project and version) - return namespaceDir.list( ).stream( ) - .map( a -> a.isContainer( ) ? a.list( ) : Collections.singletonList( a ) ) - .flatMap( List::stream ) - .map( a -> a.isContainer( ) ? a.list( ) : Collections.singletonList( a ) ) - .flatMap( List::stream ) - .filter( filter ) - .map( this::getOptionalArtifactFromPath ) - .filter( Optional::isPresent ).map( Optional::get ); - } - } - } - - /** - * Same as {@link #newArtifactStream(ContentItem)} but returns the collected stream as list. - * - * @param item the item the parent item - * @return the list of artifacts or a empty list of no artifacts where found - */ - @Override - public List getArtifacts( ContentItem item ) - { - try ( Stream stream = newArtifactStream( item ) ) - { - return stream.collect( Collectors.toList( ) ); - } - } - - /** - * Returns all artifacts - * - * @param item the namespace to search for artifacts - * @return the stream of artifacts - * @throws ContentAccessException if the access to the underlying storage failed - */ - public Stream newArtifactStream( Namespace item ) throws ContentAccessException - { - return newArtifactStream( ArchivaItemSelector.builder( ).withNamespace( item.getId( ) ).build( ) ); - } - - public Stream newArtifactStream( Project item ) throws ContentAccessException - { - return newArtifactStream( ArchivaItemSelector.builder( ).withNamespace( item.getNamespace( ).getId( ) ) - .withProjectId( item.getId( ) ).build( ) ); - } - - public Stream newArtifactStream( Version item ) throws ContentAccessException - { - return newArtifactStream( ArchivaItemSelector.builder( ).withNamespace( item.getProject( ).getNamespace( ).getId( ) ) - .withProjectId( item.getProject( ).getId( ) ) - .withVersion( item.getId( ) ).build( ) ); - } - - /** - * Returns all related artifacts that match the given artifact. That means all artifacts that have - * the same filename plus an additional extension, e.g. ${fileName}.sha2 - * - * @param item the artifact - * @return the stream of artifacts - * @throws ContentAccessException if access to the underlying storage failed - */ - public Stream newArtifactStream( Artifact item ) throws ContentAccessException - { - final Version v = item.getVersion( ); - final String fileName = item.getFileName( ); - final Predicate filter = ( StorageAsset a ) -> - a.getName( ).startsWith( fileName + "." ); - return v.getAsset( ).list( ).stream( ).filter( filter ) - .map( a -> { - try - { - return getArtifactFromPath( a ); - } - catch ( LayoutException e ) - { - log.error( "Not a valid artifact path " + a.getPath( ), e ); - return null; - } - } ).filter( Objects::nonNull ); - } - - /** - * Returns the stream of artifacts that are children of the given item. - * - * @param item the item from where the artifacts should be returned - * @return the stream of artifacts - * @throws ContentAccessException if access to the underlying storage failed - */ - @Override - public Stream newArtifactStream( ContentItem item ) throws ContentAccessException - { - if ( item instanceof Namespace ) - { - return newArtifactStream( ( (Namespace) item ) ); - } - else if ( item instanceof Project ) - { - return newArtifactStream( (Project) item ); - } - else if ( item instanceof Version ) - { - return newArtifactStream( (Version) item ); - } - else if ( item instanceof Artifact ) - { - return newArtifactStream( (Artifact) item ); - } - else - { - log.warn( "newArtifactStream for unsupported item requested: {}", item.getClass( ).getName( ) ); - return Stream.empty( ); - } - } - - private void appendPatternRegex( StringBuilder builder, String name ) - { - String[] patternArray = name.split( "[*]" ); - for ( int i = 0; i < patternArray.length - 1; i++ ) - { - builder.append( Pattern.quote( patternArray[i] ) ) - .append( "[A-Za-z0-9_\\-]*" ); - } - builder.append( Pattern.quote( patternArray[patternArray.length - 1] ) ); - } - - Predicate getItemFileFilterFromSelector( ItemSelector selector ) - { - if ( !selector.hasNamespace( ) && !selector.hasProjectId( ) ) - { - throw new IllegalArgumentException( "Selector must have at least namespace and projectid" ); - } - StringBuilder pathMatcher = new StringBuilder( "^" ); - if ( selector.hasNamespace( ) ) - { - String path = "/" + String.join( "/", selector.getNamespace( ).split( "\\." ) ); - if ( path.contains( "*" ) ) - { - appendPatternRegex( pathMatcher, path ); - } - else - { - pathMatcher.append( Pattern.quote( path ) ); - } - - } - if ( selector.hasProjectId( ) ) - { - pathMatcher.append( "/" ); - if ( selector.getProjectId( ).contains( "*" ) ) - { - appendPatternRegex( pathMatcher, selector.getProjectId( ) ); - } - else - { - pathMatcher.append( Pattern.quote( selector.getProjectId( ) ) ); - } - } - if ( selector.hasVersion( ) ) - { - pathMatcher.append( "/" ); - if ( selector.getVersion( ).contains( "*" ) ) - { - appendPatternRegex( pathMatcher, selector.getVersion( ) ); - } - else - { - pathMatcher.append( Pattern.quote( selector.getVersion( ) ) ); - } - } - pathMatcher.append( ".*" ); - final Pattern pathPattern = Pattern.compile( pathMatcher.toString( ) ); - final Predicate pathPredicate = ( StorageAsset asset ) -> pathPattern.matcher( asset.getPath( ) ).matches( ); - if ( selector.hasArtifactId( ) || selector.hasArtifactVersion( ) || selector.hasClassifier( ) - || selector.hasType( ) || selector.hasExtension( ) ) - { - return getArtifactFileFilterFromSelector( selector ).and( pathPredicate ); - } - else - { - return pathPredicate; - } - } - - /** - * Returns a concatenation of the asset and its children as stream, if they exist. - * It descends level+1 levels down. - * - * @param a the asset to start from - * @param level the number of child levels to descend. 0 means only the children of the given asset, 1 means the children of childrens of the given asset, ... - * @return the stream of storage assets - */ - private Stream getChildrenDF( StorageAsset a, int level ) - { - if ( a.isContainer( ) ) - { - if (level>0) { - return Stream.concat( a.list().stream( ).flatMap( ch -> getChildrenDF( ch, level - 1 ) ), Stream.of( a ) ); - } else - { - return Stream.concat( a.list( ).stream( ), Stream.of( a ) ); - } - } - else - { - return Stream.of( a ); - } - } - - @Override - public Stream newItemStream( ItemSelector selector, boolean parallel ) throws ContentAccessException, IllegalArgumentException - { - final Predicate filter = getItemFileFilterFromSelector( selector ); - StorageAsset startDir; - if (selector.getNamespace().contains("*")) { - startDir = getAsset(""); - } else if ( selector.hasProjectId( ) && selector.getProjectId().contains("*") ) - { - startDir = getAsset( selector.getNamespace( ) ); - } else if ( selector.hasProjectId() && selector.hasVersion() && selector.getVersion().contains("*")) { - startDir = getAsset( selector.getNamespace( ), selector.getProjectId( ) ); - } - else if ( selector.hasProjectId( ) && selector.hasVersion( ) ) - { - startDir = getAsset( selector.getNamespace( ), selector.getProjectId( ), selector.getVersion() ); - } - else if ( selector.hasProjectId( ) ) - { - startDir = getAsset( selector.getNamespace( ), selector.getProjectId( ) ); - } - else - { - startDir = getAsset( selector.getNamespace( ) ); - if ( !selector.recurse( ) ) - { - // We descend into 2 subdirectories (project and version) - return startDir.list( ).stream( ) - .flatMap( a -> getChildrenDF( a, 1 ) ) - .map( this::getItemFromPath ); - } - } - return StorageUtil.newAssetStream( startDir, parallel ) - .filter( filter ) - .map( this::getItemFromPath ); - - } - - /** - * Checks, if the asset/file queried by the given selector exists. - */ - @Override - public boolean hasContent( ItemSelector selector ) - { - return getItem( selector ).getAsset( ).exists( ); - } - - @Override - public ContentItem getParent( ContentItem item ) - { - return getItemFromPath( item.getAsset( ).getParent( ) ); - } - - @Override - public List getChildren( ContentItem item ) - { - if (item.getAsset().isLeaf()) { - return Collections.emptyList( ); - } else { - return item.getAsset( ).list( ).stream( ).map( this::getItemFromPath ).collect( Collectors.toList( ) ); - } - } - - @Override - public T applyCharacteristic( Class clazz, ContentItem item ) throws LayoutException - { - if (item.getAsset().isLeaf()) { - if (clazz.isAssignableFrom( Artifact.class )) { - Artifact artifact = getArtifactFromPath( item.getAsset( ) ); - item.setCharacteristic( Artifact.class, artifact ); - return (T) artifact; - } else { - throw new LayoutException( "Could not adapt file to clazz " + clazz ); - } - } else { - if (clazz.isAssignableFrom( Version.class )) { - Version version = getVersionFromPath( item.getAsset( ) ); - item.setCharacteristic( Version.class, version ); - return (T) version; - } else if (clazz.isAssignableFrom( Project.class )) { - Project project = getProjectFromPath( item.getAsset( ) ); - item.setCharacteristic( Project.class, project ); - return (T) project; - } else if (clazz.isAssignableFrom( Namespace.class )) { - Namespace ns = getNamespaceFromPath( item.getAsset( ) ); - item.setCharacteristic( Namespace.class, ns ); - return (T) ns; - } else { - throw new LayoutException( "Cannot adapt directory to clazz " + clazz ); - } - } - } - - @Override - public T getLayout( Class clazz ) throws LayoutException - { - if (clazz.isAssignableFrom( this.getClass() )) { - return (T) this; - } else { - throw new LayoutException( "Cannot convert to layout " + clazz ); - } - } - - @Override - public boolean supportsLayout( Class clazz ) - { - return clazz.isAssignableFrom( this.getClass( ) ); - } - - @Override - public List> getSupportedLayouts( ) - { - return LAYOUTS; - } - - /** - * Moves the file to the artifact destination - */ - @Override - public void addArtifact( Path sourceFile, Artifact destination ) throws IllegalArgumentException, ContentAccessException - { - try - { - StorageAsset asset = destination.getAsset( ); - if ( !asset.exists( ) ) - { - asset.create( ); - } - asset.replaceDataFromFile( sourceFile ); - } - catch ( IOException e ) - { - log.error( "Could not push data to asset source={} destination={}. {}", sourceFile, destination.getAsset( ).getFilePath( ), e.getMessage( ) ); - throw new ContentAccessException( e.getMessage( ), e ); - } - } - - @Override - public ContentItem toItem( String path ) throws LayoutException - { - - StorageAsset asset = getRepository( ).getAsset( path ); - ContentItem item = getItemFromPath( asset ); - if (item instanceof DataItem) { - Artifact artifact = adaptItem( Artifact.class, item ); - if (asset.getParent()==null) { - throw new LayoutException( "Path too short for maven artifact "+path ); - } - String version = asset.getParent( ).getName( ); - if (asset.getParent().getParent()==null) { - throw new LayoutException( "Path too short for maven artifact " + path ); - } - String project = item.getAsset( ).getParent( ).getParent( ).getName( ); - DataItem dataItem = (DataItem) item; - if (StringUtils.isEmpty( dataItem.getExtension())) { - throw new LayoutException( "Missing type on maven artifact" ); - } - if (!project.equals(artifact.getId())) { - throw new LayoutException( "The maven artifact id "+artifact.getId() +" does not match the project id: " + project); - } - boolean versionIsGenericSnapshot = VersionUtil.isGenericSnapshot( version ); - boolean artifactVersionIsSnapshot = VersionUtil.isSnapshot( artifact.getArtifactVersion() ); - if ( versionIsGenericSnapshot && !artifactVersionIsSnapshot ) { - throw new LayoutException( "The maven artifact has no snapshot version in snapshot directory " + dataItem ); - } - if ( !versionIsGenericSnapshot && artifactVersionIsSnapshot) { - throw new LayoutException( "The maven artifact version " + artifact.getArtifactVersion() + " is a snapshot version but inside a non snapshot directory " + version ); - } - if ( !versionIsGenericSnapshot && !version.equals( artifact.getArtifactVersion() ) ) - { - throw new LayoutException( "The maven artifact version " + artifact.getArtifactVersion() + " does not match the version directory " + version ); - } - } - return item; - } - - @Override - public ContentItem toItem( StorageAsset assetPath ) throws LayoutException - { - return toItem( assetPath.getPath( ) ); - } - - /// ************* End of new generation interface ****************** - - @Override - public String toPath( ContentItem item ) { - return item.getAsset( ).getPath( ); - } - - @Override - public DataItem getMetadataItem( Version version ) { - StorageAsset metaPath = version.getAsset( ).resolve( MAVEN_METADATA ); - return getDataItemFromPath( metaPath ); - } - - @Override - public DataItem getMetadataItem( Project project ) - { - StorageAsset metaPath = project.getAsset( ).resolve( MAVEN_METADATA ); - return getDataItemFromPath( metaPath ); - } - - - @Override - public String getId( ) - { - return repository.getId( ); - } - - @Override - public ManagedRepository getRepository( ) - { - return repository; - } - - @Override - public void setRepository( final ManagedRepository repo ) - { - this.repository = repo; - if ( repo != null ) - { - if ( repository instanceof EditableManagedRepository ) - { - ( (EditableManagedRepository) repository ).setContent( this ); - } - } - } - - private Path getRepoDir( ) - { - return repository.getRoot().getFilePath( ); - } - - private RepositoryStorage getStorage( ) - { - return repository.getRoot().getStorage( ); - } - - public void setFiletypes( FileTypes filetypes ) - { - this.filetypes = filetypes; - } - - public void setMavenContentHelper( MavenContentHelper contentHelper ) - { - this.mavenContentHelper = contentHelper; - } - - - public MavenMetadataReader getMetadataReader( ) - { - return metadataReader; - } - - public void setMetadataReader( MavenMetadataReader metadataReader ) - { - this.metadataReader = metadataReader; - } -} diff --git a/archiva-modules/archiva-maven/archiva-maven-repository/src/main/java/org/apache/archiva/repository/maven/content/MavenContentHelper.java b/archiva-modules/archiva-maven/archiva-maven-repository/src/main/java/org/apache/archiva/repository/maven/content/MavenContentHelper.java deleted file mode 100644 index 60a9a5562..000000000 --- a/archiva-modules/archiva-maven/archiva-maven-repository/src/main/java/org/apache/archiva/repository/maven/content/MavenContentHelper.java +++ /dev/null @@ -1,290 +0,0 @@ -package org.apache.archiva.repository.maven.content; - -/* - * 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.utils.VersionUtil; -import org.apache.archiva.maven.metadata.MavenMetadataReader; -import org.apache.archiva.model.ArchivaRepositoryMetadata; -import org.apache.archiva.model.SnapshotVersion; -import org.apache.archiva.repository.content.ItemSelector; -import org.apache.archiva.repository.metadata.RepositoryMetadataException; -import org.apache.archiva.repository.storage.StorageAsset; -import org.apache.commons.lang3.StringUtils; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.stereotype.Service; - -import javax.inject.Inject; -import javax.inject.Named; -import java.util.Comparator; -import java.util.LinkedList; -import java.util.regex.Pattern; - -/** - * Helper class that contains certain maven specific methods - */ -@Service( "MavenContentHelper" ) -public class MavenContentHelper -{ - - private static final Logger log = LoggerFactory.getLogger( MavenContentHelper.class ); - public static final Pattern UNIQUE_SNAPSHOT_NUMBER_PATTERN = Pattern.compile( "^([0-9]{8}\\.[0-9]{6}-[0-9]+)(.*)" ); - - - @Inject - @Named( "metadataReader#maven" ) - MavenMetadataReader metadataReader; - - public static final String METADATA_FILENAME = "maven-metadata.xml"; - public static final String METADATA_REPOSITORY_FILENAME = "maven-metadata-repository.xml"; - - public MavenContentHelper() { - - } - - public void setMetadataReader( MavenMetadataReader metadataReader ) - { - this.metadataReader = metadataReader; - } - - /** - * Returns the namespace string for a given path in the repository - * - * @param namespacePath the path to the namespace in the directory - * @return the namespace string that matches the given path. - */ - public static String getNamespaceFromNamespacePath( final StorageAsset namespacePath) { - LinkedList names = new LinkedList<>( ); - StorageAsset current = namespacePath; - while (current.hasParent()) { - names.addFirst( current.getName() ); - current = current.getParent( ); - } - return String.join( ".", names ); - } - - /** - * Returns the artifact version for the given artifact directory and the item selector - */ - public String getArtifactVersion( StorageAsset artifactDir, ItemSelector selector) { - if (selector.hasArtifactVersion()) { - return selector.getArtifactVersion(); - } else if (selector.hasVersion()) { - if ( VersionUtil.isGenericSnapshot( selector.getVersion() ) ) { - return getLatestArtifactSnapshotVersion( artifactDir, selector.getVersion( ) ); - } else { - return selector.getVersion( ); - } - } else { - throw new IllegalArgumentException( "No version set on the selector " ); - } - } - - - /** - * - * Returns the latest snapshot version that is referenced by the metadata file. - * - * @param artifactDir the directory of the artifact - * @param snapshotVersion the generic snapshot version (must end with '-SNAPSHOT') - * @return the real version from the metadata - */ - public String getLatestArtifactSnapshotVersion( StorageAsset artifactDir, String snapshotVersion) { - final StorageAsset metadataFile = artifactDir.resolve( METADATA_FILENAME ); - StringBuilder version = new StringBuilder( ); - try - { - ArchivaRepositoryMetadata metadata = metadataReader.read( metadataFile ); - - // re-adjust to timestamp if present, otherwise retain the original -SNAPSHOT filename - SnapshotVersion metadataVersion = metadata.getSnapshotVersion( ); - if ( metadataVersion != null && StringUtils.isNotEmpty( metadataVersion.getTimestamp( ) ) ) - { - version.append( snapshotVersion, 0, snapshotVersion.length( ) - 8 ); // remove SNAPSHOT from end - version.append( metadataVersion.getTimestamp( ) ).append( "-" ).append( metadataVersion.getBuildNumber( ) ); - return version.toString( ); - } - } - catch ( RepositoryMetadataException e ) - { - // unable to parse metadata - LOGGER it, and continue with the version as the original SNAPSHOT version - log.warn( "Invalid metadata: {} - {}", metadataFile, e.getMessage( ) ); - } - final String baseVersion = StringUtils.removeEnd( snapshotVersion, "-SNAPSHOT" ); - final String prefix = metadataFile.getParent( ).getParent( ).getName( ) + "-"+baseVersion+"-"; - return artifactDir.list( ).stream( ).filter( a -> a.getName( ).startsWith( prefix ) ) - .map( a -> StringUtils.removeStart( a.getName( ), prefix ) ) - .map( n -> UNIQUE_SNAPSHOT_NUMBER_PATTERN.matcher( n ) ) - .filter( m -> m.matches( ) ) - .map( m -> baseVersion+"-"+m.group( 1 ) ) - .sorted( Comparator.reverseOrder() ).findFirst().orElse( snapshotVersion ); - } - - - /** - * Returns a artifact filename that corresponds to the given data. - * @param artifactId the selector data - * @param artifactVersion the artifactVersion - * @param classifier the artifact classifier - * @param extension the file extension - */ - static String getArtifactFileName( String artifactId, String artifactVersion, - String classifier, String extension ) - { - StringBuilder fileName = new StringBuilder( artifactId ).append( "-" ); - fileName.append( artifactVersion ); - if ( !StringUtils.isEmpty( classifier ) ) - { - fileName.append( "-" ).append( classifier ); - } - fileName.append( "." ).append( extension ); - return fileName.toString( ); - } - - /** - * Returns the classifier for a given selector. If the selector has no classifier, but - * a type set. The classifier is generated from the type. - * - * @param selector the artifact selector - * @return the classifier or empty string if no classifier was found - */ - static String getClassifier( ItemSelector selector ) - { - if ( selector.hasClassifier( ) ) - { - return selector.getClassifier( ); - } - else if ( selector.hasType( ) ) - { - return getClassifierFromType( selector.getType( ) ); - } - else - { - return ""; - } - } - - /** - * Returns a classifier for a given type. It returns only classifier for the maven default types - * that are known. - * - * @param type the type of the artifact - * @return the classifier if one was found, otherwise a empty string - */ - static String getClassifierFromType( final String type ) - { - String testType = type.trim( ).toLowerCase( ); - switch (testType.length( )) - { - case 7: - if ("javadoc".equals(testType)) { - return "javadoc"; - } - case 8: - if ("test-jar".equals(testType)) - { - return "tests"; - } - case 10: - if ("ejb-client".equals(testType)) { - return "client"; - } - case 11: - if ("java-source".equals(testType)) { - return "sources"; - } - default: - return ""; - } - - } - - /** - * Returns the type that matches the given classifier and extension - * - * @param classifierArg the classifier - * @param extensionArg the extension - * @return the type that matches the combination of classifier and extension - */ - static String getTypeFromClassifierAndExtension( String classifierArg, String extensionArg ) - { - String extension = extensionArg.toLowerCase( ).trim( ); - String classifier = classifierArg.toLowerCase( ).trim( ); - if ( StringUtils.isEmpty( extension ) ) - { - return ""; - } - else if ( StringUtils.isEmpty( classifier ) ) - { - return extension; - } - else if ( classifier.equals( "tests" ) && extension.equals( "jar" ) ) - { - return "test-jar"; - } - else if ( classifier.equals( "client" ) && extension.equals( "jar" ) ) - { - return "ejb-client"; - } - else if ( classifier.equals( "sources" ) && extension.equals( "jar" ) ) - { - return "java-source"; - } - else if ( classifier.equals( "javadoc" ) && extension.equals( "jar" ) ) - { - return "javadoc"; - } - else - { - return extension; - } - } - - /** - * If the selector defines a type and no extension, the extension can be derived from - * the type. - * - * @param selector the item selector - * @return the extension that matches the type or the default extension "jar" if the type is not known - */ - static String getArtifactExtension( ItemSelector selector ) - { - if ( selector.hasExtension( ) ) - { - return selector.getExtension( ); - } - else if ( selector.hasType( ) ) - { - final String type = selector.getType( ).trim().toLowerCase( ); - switch (type.length()) { - case 3: - if ("pom".equals(type) || "war".equals(type) || "ear".equals(type) || "rar".equals(type)) { - return type; - } - default: - return "jar"; - - } - } - else - { - return "jar"; - } - } -} diff --git a/archiva-modules/archiva-maven/archiva-maven-repository/src/main/java/org/apache/archiva/repository/maven/content/MavenContentProvider.java b/archiva-modules/archiva-maven/archiva-maven-repository/src/main/java/org/apache/archiva/repository/maven/content/MavenContentProvider.java deleted file mode 100644 index e164a4a02..000000000 --- a/archiva-modules/archiva-maven/archiva-maven-repository/src/main/java/org/apache/archiva/repository/maven/content/MavenContentProvider.java +++ /dev/null @@ -1,140 +0,0 @@ -package org.apache.archiva.repository.maven.content; - -/* - * 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.filelock.FileLockManager; -import org.apache.archiva.configuration.FileTypes; -import org.apache.archiva.metadata.repository.storage.RepositoryPathTranslator; -import org.apache.archiva.repository.ManagedRepository; -import org.apache.archiva.repository.ManagedRepositoryContent; -import org.apache.archiva.repository.RemoteRepository; -import org.apache.archiva.repository.RemoteRepositoryContent; -import org.apache.archiva.repository.Repository; -import org.apache.archiva.repository.RepositoryContent; -import org.apache.archiva.repository.RepositoryContentProvider; -import org.apache.archiva.repository.RepositoryException; -import org.apache.archiva.repository.RepositoryType; -import org.apache.archiva.repository.content.BaseRepositoryContentLayout; -import org.apache.archiva.repository.maven.metadata.storage.ArtifactMappingProvider; -import org.springframework.stereotype.Service; - -import javax.inject.Inject; -import javax.inject.Named; -import java.util.HashSet; -import java.util.List; -import java.util.Set; - -/** - * Maven implementation of the repository content provider. Only default layout and - * maven repository types are supported. - */ -@Service("repositoryContentProvider#maven") -public class MavenContentProvider implements RepositoryContentProvider -{ - - @Inject - @Named( "fileTypes" ) - private FileTypes filetypes; - - @Inject - private FileLockManager fileLockManager; - - @Inject - protected List artifactMappingProviders; - - @Inject - @Named("MavenContentHelper") - MavenContentHelper mavenContentHelper; - - @Inject - @Named("repositoryPathTranslator#maven2") - RepositoryPathTranslator pathTranslator; - - private static final Set REPOSITORY_TYPES = new HashSet<>( ); - static { - REPOSITORY_TYPES.add(RepositoryType.MAVEN); - } - - @Override - public boolean supportsLayout( String layout ) - { - return "default".equals( layout ); - } - - @Override - public Set getSupportedRepositoryTypes( ) - { - return REPOSITORY_TYPES; - } - - @Override - public boolean supports( RepositoryType type ) - { - return type.equals( RepositoryType.MAVEN ); - } - - @Override - public RemoteRepositoryContent createRemoteContent( RemoteRepository repository ) throws RepositoryException - { - if (!supports( repository.getType() )) { - throw new RepositoryException( "Repository type "+repository.getType()+" is not supported by this implementation." ); - } - if (!supportsLayout( repository.getLayout() )) { - throw new RepositoryException( "Repository layout "+repository.getLayout()+" is not supported by this implementation." ); - } - RemoteDefaultRepositoryContent content = new RemoteDefaultRepositoryContent(); - content.setRepository( repository ); - content.setPathTranslator( pathTranslator ); - content.setArtifactMappingProviders( artifactMappingProviders ); - return content; - } - - @Override - public ManagedRepositoryContent createManagedContent( ManagedRepository repository ) throws RepositoryException - { - if (!supports( repository.getType() )) { - throw new RepositoryException( "Repository type "+repository.getType()+" is not supported by this implementation." ); - } - if (!supportsLayout( repository.getLayout() )) { - throw new RepositoryException( "Repository layout "+repository.getLayout()+" is not supported by this implementation." ); - } - ManagedDefaultRepositoryContent content = new ManagedDefaultRepositoryContent(repository, filetypes ,fileLockManager); - content.setMavenContentHelper( mavenContentHelper ); - content.setPathTranslator( pathTranslator ); - content.setArtifactMappingProviders( artifactMappingProviders ); - return content; - } - - @SuppressWarnings( "unchecked" ) - @Override - public T createContent( Class clazz, V repository ) throws RepositoryException - { - if (!supports( repository.getType() )) { - throw new RepositoryException( "Repository type "+repository.getType()+" is not supported by this implementation." ); - } - if (repository instanceof ManagedRepository && BaseRepositoryContentLayout.class.isAssignableFrom( clazz ) ) { - return (T) this.createManagedContent( (ManagedRepository) repository ); - } else if (repository instanceof RemoteRepository && RemoteRepository.class.isAssignableFrom( clazz )) { - return (T) this.createRemoteContent( (RemoteRepository) repository ); - } else { - throw new RepositoryException( "Repository flavour is not supported: "+repository.getClass().getName() ); - } - } - -} diff --git a/archiva-modules/archiva-maven/archiva-maven-repository/src/main/java/org/apache/archiva/repository/maven/content/MavenRepositoryRequestInfo.java b/archiva-modules/archiva-maven/archiva-maven-repository/src/main/java/org/apache/archiva/repository/maven/content/MavenRepositoryRequestInfo.java deleted file mode 100644 index 18e8c458c..000000000 --- a/archiva-modules/archiva-maven/archiva-maven-repository/src/main/java/org/apache/archiva/repository/maven/content/MavenRepositoryRequestInfo.java +++ /dev/null @@ -1,267 +0,0 @@ -package org.apache.archiva.repository.maven.content; - -/* - * 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.repository.ManagedRepository; -import org.apache.archiva.repository.RepositoryRequestInfo; -import org.apache.archiva.repository.UnsupportedFeatureException; -import org.apache.archiva.repository.content.BaseRepositoryContentLayout; -import org.apache.archiva.repository.content.ItemSelector; -import org.apache.archiva.repository.content.LayoutException; -import org.apache.archiva.repository.features.RepositoryFeature; -import org.apache.archiva.repository.metadata.base.MetadataTools; -import org.apache.commons.lang3.StringUtils; - -/** - * RepositoryRequest is used to determine the type of request that is incoming, and convert it to an appropriate - * ArtifactReference. - */ -public class MavenRepositoryRequestInfo implements RepositoryRequestInfo -{ - ManagedRepository repository; - - public MavenRepositoryRequestInfo(ManagedRepository repository) - { - this.repository = repository; - } - - @Override - public ItemSelector toItemSelector( String requestPath ) throws LayoutException - { - return repository.getContent( ).toItemSelector( requestPath ); - } - - /** - *

- * Tests the path to see if it conforms to the expectations of a metadata request. - *

- *

- * NOTE: This does a cursory check on the path's last element. A result of true - * from this method is not a guarantee that the metadata is in a valid format, or - * that it even contains data. - *

- * - * @param requestedPath the path to test. - * @return true if the requestedPath is likely a metadata request. - */ - public boolean isMetadata( String requestedPath ) - { - return requestedPath.endsWith( "/" + MetadataTools.MAVEN_METADATA ); - } - - /** - * @param requestedPath - * @return true if the requestedPath is likely an archetype catalog request. - */ - public boolean isArchetypeCatalog( String requestedPath ) - { - return requestedPath.endsWith( "/" + MetadataTools.MAVEN_ARCHETYPE_CATALOG ); - } - - /** - *

- * Tests the path to see if it conforms to the expectations of a support file request. - *

- *

- * Tests for .sha1, .md5, .asc, and .php. - *

- *

- * NOTE: This does a cursory check on the path's extension only. A result of true - * from this method is not a guarantee that the support resource is in a valid format, or - * that it even contains data. - *

- * - * @param requestedPath the path to test. - * @return true if the requestedPath is likely that of a support file request. - */ - public boolean isSupportFile( String requestedPath ) - { - int idx = requestedPath.lastIndexOf( '.' ); - if ( idx <= 0 ) - { - return false; - } - - String ext = requestedPath.substring( idx ); - return ( ".sha1".equals( ext ) || ".md5".equals( ext ) || ".asc".equals( ext ) || ".pgp".equals( ext ) ); - } - - public boolean isMetadataSupportFile( String requestedPath ) - { - if ( isSupportFile( requestedPath ) ) - { - String basefilePath = StringUtils.substring( requestedPath, 0, requestedPath.lastIndexOf( '.' ) ); - if ( isMetadata( basefilePath ) ) - { - return true; - } - } - - return false; - } - - @Override - public String getLayout(String requestPath) { - if (isDefault(requestPath)) { - return "default"; - } else if (isLegacy(requestPath)) { - return "legacy"; - } else { - return "unknown"; - } - } - - /** - *

- * Tests the path to see if it conforms to the expectations of a default layout request. - *

- *

- * NOTE: This does a cursory check on the count of path elements only. A result of - * true from this method is not a guarantee that the path sections are valid and - * can be resolved to an artifact reference. use {@link #toItemSelector(String)} - * if you want a more complete analysis of the validity of the path. - *

- * - * @param requestedPath the path to test. - * @return true if the requestedPath is likely that of a default layout request. - */ - private boolean isDefault( String requestedPath ) - { - if ( StringUtils.isBlank( requestedPath ) ) - { - return false; - } - - String pathParts[] = StringUtils.splitPreserveAllTokens( requestedPath, '/' ); - if ( pathParts.length > 3 ) - { - return true; - } - else if ( pathParts.length == 3 ) - { - // check if artifact-level metadata (ex. eclipse/jdtcore/maven-metadata.xml) - if ( isMetadata( requestedPath ) ) - { - return true; - } - else - { - // check if checksum of artifact-level metadata (ex. eclipse/jdtcore/maven-metadata.xml.sha1) - int idx = requestedPath.lastIndexOf( '.' ); - if ( idx > 0 ) - { - String base = requestedPath.substring( 0, idx ); - if ( isMetadata( base ) && isSupportFile( requestedPath ) ) - { - return true; - } - } - - return false; - } - } - else - { - return false; - } - } - - /** - *

- * Tests the path to see if it conforms to the expectations of a legacy layout request. - *

- *

- * NOTE: This does a cursory check on the count of path elements only. A result of - * true from this method is not a guarantee that the path sections are valid and - * can be resolved to an artifact reference. Use {@link #toItemSelector(String)} - * if you want a more complete analysis of the validity of the path. - *

- * - * @param requestedPath the path to test. - * @return true if the requestedPath is likely that of a legacy layout request. - */ - private boolean isLegacy( String requestedPath ) - { - if ( StringUtils.isBlank( requestedPath ) ) - { - return false; - } - - String pathParts[] = StringUtils.splitPreserveAllTokens( requestedPath, '/' ); - return pathParts.length == 3; - } - - /** - * Adjust the requestedPath to conform to the native layout of the provided {@link BaseRepositoryContentLayout}. - * - * @param requestedPath the incoming requested path. - * @return the adjusted (to native) path. - * @throws LayoutException if the path cannot be parsed. - */ - public String toNativePath( String requestedPath) - throws LayoutException - { - if ( StringUtils.isBlank( requestedPath ) ) - { - throw new LayoutException( "Request Path is blank." ); - } - - String referencedResource = requestedPath; - // No checksum by default. - String supportfile = ""; - - // Figure out support file, and actual referencedResource. - if ( isSupportFile( requestedPath ) ) - { - int idx = requestedPath.lastIndexOf( '.' ); - referencedResource = requestedPath.substring( 0, idx ); - supportfile = requestedPath.substring( idx ); - } - - if ( isMetadata( referencedResource ) ) - { - /* Nothing to translate. - * Default layout is the only layout that can contain maven-metadata.xml files, and - * if the managedRepository is layout legacy, this request would never occur. - */ - if (requestedPath.startsWith( "/" )) { - return requestedPath; - } else - { - return "/"+requestedPath; - } - } - - - - // Treat as an artifact reference. - String adjustedPath = repository.getContent( ).toPath( repository.getContent( ).toItem( requestedPath ) ); - return adjustedPath + supportfile; - } - - @Override - public > RepositoryFeature getFeature(Class clazz) throws UnsupportedFeatureException { - return null; - } - - @Override - public > boolean supportsFeature(Class clazz) { - return false; - } -} diff --git a/archiva-modules/archiva-maven/archiva-maven-repository/src/main/java/org/apache/archiva/repository/maven/content/MavenTypes.java b/archiva-modules/archiva-maven/archiva-maven-repository/src/main/java/org/apache/archiva/repository/maven/content/MavenTypes.java deleted file mode 100644 index e98603916..000000000 --- a/archiva-modules/archiva-maven/archiva-maven-repository/src/main/java/org/apache/archiva/repository/maven/content/MavenTypes.java +++ /dev/null @@ -1,29 +0,0 @@ -package org.apache.archiva.repository.maven.content; - -/* - * 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.repository.content.ArtifactType; - -/** - * @author Martin Stockhammer - */ -public enum MavenTypes implements ArtifactType -{ - REPOSITORY_METADATA -} diff --git a/archiva-modules/archiva-maven/archiva-maven-repository/src/main/java/org/apache/archiva/repository/maven/content/RemoteDefaultRepositoryContent.java b/archiva-modules/archiva-maven/archiva-maven-repository/src/main/java/org/apache/archiva/repository/maven/content/RemoteDefaultRepositoryContent.java deleted file mode 100644 index 09876cb9b..000000000 --- a/archiva-modules/archiva-maven/archiva-maven-repository/src/main/java/org/apache/archiva/repository/maven/content/RemoteDefaultRepositoryContent.java +++ /dev/null @@ -1,56 +0,0 @@ -package org.apache.archiva.repository.maven.content; - -/* - * 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.repository.RemoteRepository; -import org.apache.archiva.repository.RemoteRepositoryContent; - -/** - * RemoteDefaultRepositoryContent - */ -public class RemoteDefaultRepositoryContent - extends AbstractDefaultRepositoryContent - implements RemoteRepositoryContent -{ - private RemoteRepository repository; - - - public RemoteDefaultRepositoryContent( ) { - super(); - } - - @Override - public String getId( ) - { - return repository.getId( ); - } - - @Override - public RemoteRepository getRepository( ) - { - return repository; - } - - @Override - public void setRepository( RemoteRepository repository ) - { - this.repository = repository; - } - -} diff --git a/archiva-modules/archiva-maven/archiva-maven-repository/src/main/java/org/apache/archiva/repository/maven/dependency/tree/ArchivaRepositoryConnectorFactory.java b/archiva-modules/archiva-maven/archiva-maven-repository/src/main/java/org/apache/archiva/repository/maven/dependency/tree/ArchivaRepositoryConnectorFactory.java deleted file mode 100644 index c8a632b00..000000000 --- a/archiva-modules/archiva-maven/archiva-maven-repository/src/main/java/org/apache/archiva/repository/maven/dependency/tree/ArchivaRepositoryConnectorFactory.java +++ /dev/null @@ -1,100 +0,0 @@ -package org.apache.archiva.repository.maven.dependency.tree; -/* - * 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.eclipse.aether.RepositorySystemSession; -import org.eclipse.aether.connector.basic.BasicRepositoryConnectorFactory; -import org.eclipse.aether.internal.impl.DefaultRepositoryLayoutProvider; -import org.eclipse.aether.repository.RemoteRepository; -import org.eclipse.aether.spi.connector.ArtifactDownload; -import org.eclipse.aether.spi.connector.ArtifactUpload; -import org.eclipse.aether.spi.connector.MetadataDownload; -import org.eclipse.aether.spi.connector.MetadataUpload; -import org.eclipse.aether.spi.connector.RepositoryConnector; -import org.eclipse.aether.spi.connector.RepositoryConnectorFactory; -import org.eclipse.aether.transfer.NoRepositoryConnectorException; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import java.util.Collection; - -/** - * - * Creates a dummy connector, if the default connectory factory fails to create one. - * - * @author Olivier Lamy - * @since 1.4-M3 - */ -public class ArchivaRepositoryConnectorFactory - implements RepositoryConnectorFactory -{ - - private BasicRepositoryConnectorFactory delegate = new BasicRepositoryConnectorFactory(); - - public ArchivaRepositoryConnectorFactory() - { - // no op but empty constructor needed by aether - delegate.setRepositoryLayoutProvider(new DefaultRepositoryLayoutProvider()); - } - - @Override - public RepositoryConnector newInstance( RepositorySystemSession session, RemoteRepository repository ) - throws NoRepositoryConnectorException - { - try - { - return delegate.newInstance( session, repository ); - } - catch ( NoRepositoryConnectorException e ) - { - - } - - return new RepositoryConnector() - { - - private Logger log = LoggerFactory.getLogger( getClass() ); - - @Override - public void get( Collection artifactDownloads, - Collection metadataDownloads ) - { - log.debug( "get" ); - } - - @Override - public void put( Collection artifactUploads, - Collection metadataUploads ) - { - log.debug( "put" ); - } - - @Override - public void close() - { - log.debug( "close" ); - } - }; - } - - @Override - public float getPriority( ) - { - return 0; - } -} diff --git a/archiva-modules/archiva-maven/archiva-maven-repository/src/main/java/org/apache/archiva/repository/maven/dependency/tree/DependencyTreeBuilder.java b/archiva-modules/archiva-maven/archiva-maven-repository/src/main/java/org/apache/archiva/repository/maven/dependency/tree/DependencyTreeBuilder.java deleted file mode 100644 index d1d2f6a1a..000000000 --- a/archiva-modules/archiva-maven/archiva-maven-repository/src/main/java/org/apache/archiva/repository/maven/dependency/tree/DependencyTreeBuilder.java +++ /dev/null @@ -1,37 +0,0 @@ -package org.apache.archiva.repository.maven.dependency.tree; -/* - * 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.maven.model.TreeEntry; -import org.eclipse.aether.graph.DependencyVisitor; - -import java.util.List; - -/** - * @author Olivier Lamy - */ -public interface DependencyTreeBuilder -{ - void buildDependencyTree( List repositoryIds, String groupId, String artifactId, String version, - DependencyVisitor dependencyVisitor ) - throws Exception; - - List buildDependencyTree( List repositoryIds, String groupId, String artifactId, String version ) - throws Exception; -} - diff --git a/archiva-modules/archiva-maven/archiva-maven-repository/src/main/java/org/apache/archiva/repository/maven/dependency/tree/DependencyTreeBuilderException.java b/archiva-modules/archiva-maven/archiva-maven-repository/src/main/java/org/apache/archiva/repository/maven/dependency/tree/DependencyTreeBuilderException.java deleted file mode 100644 index 527b52409..000000000 --- a/archiva-modules/archiva-maven/archiva-maven-repository/src/main/java/org/apache/archiva/repository/maven/dependency/tree/DependencyTreeBuilderException.java +++ /dev/null @@ -1,31 +0,0 @@ -package org.apache.archiva.repository.maven.dependency.tree; -/* - * 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-M3 - */ -public class DependencyTreeBuilderException - extends Exception -{ - public DependencyTreeBuilderException( String message, Throwable t ) - { - super( message, t ); - } -} diff --git a/archiva-modules/archiva-maven/archiva-maven-repository/src/main/java/org/apache/archiva/repository/maven/dependency/tree/Maven3DependencyTreeBuilder.java b/archiva-modules/archiva-maven/archiva-maven-repository/src/main/java/org/apache/archiva/repository/maven/dependency/tree/Maven3DependencyTreeBuilder.java deleted file mode 100644 index b908f9edb..000000000 --- a/archiva-modules/archiva-maven/archiva-maven-repository/src/main/java/org/apache/archiva/repository/maven/dependency/tree/Maven3DependencyTreeBuilder.java +++ /dev/null @@ -1,302 +0,0 @@ -package org.apache.archiva.repository.maven.dependency.tree; -/* - * 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.admin.model.RepositoryAdminException; -import org.apache.archiva.admin.model.beans.NetworkProxy; -import org.apache.archiva.admin.model.beans.ProxyConnector; -import org.apache.archiva.admin.model.networkproxy.NetworkProxyAdmin; -import org.apache.archiva.admin.model.proxyconnector.ProxyConnectorAdmin; -import org.apache.archiva.common.utils.VersionUtil; -import org.apache.archiva.maven.model.TreeEntry; -import org.apache.archiva.maven.metadata.MavenMetadataReader; -import org.apache.archiva.metadata.repository.storage.RepositoryPathTranslator; -import org.apache.archiva.model.ArchivaRepositoryMetadata; -import org.apache.archiva.repository.ManagedRepository; -import org.apache.archiva.repository.RemoteRepository; -import org.apache.archiva.repository.RepositoryRegistry; -import org.apache.archiva.repository.maven.MavenSystemManager; -import org.apache.archiva.repository.metadata.RepositoryMetadataException; -import org.apache.archiva.repository.metadata.base.MetadataTools; -import org.apache.archiva.repository.storage.StorageAsset; -import org.apache.commons.lang3.StringUtils; -import org.apache.commons.lang3.reflect.FieldUtils; -import org.apache.maven.artifact.Artifact; -import org.apache.maven.artifact.handler.manager.DefaultArtifactHandlerManager; -import org.apache.maven.artifact.repository.layout.ArtifactRepositoryLayout; -import org.apache.maven.artifact.repository.layout.DefaultRepositoryLayout; -import org.apache.maven.bridge.MavenRepositorySystem; -import org.eclipse.aether.RepositorySystem; -import org.eclipse.aether.RepositorySystemSession; -import org.eclipse.aether.artifact.DefaultArtifact; -import org.eclipse.aether.collection.CollectRequest; -import org.eclipse.aether.collection.CollectResult; -import org.eclipse.aether.collection.DependencyCollectionException; -import org.eclipse.aether.graph.Dependency; -import org.eclipse.aether.graph.DependencyVisitor; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.stereotype.Service; - -import javax.annotation.PostConstruct; -import javax.inject.Inject; -import javax.inject.Named; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -/** - * @author Olivier Lamy - * @since 1.4-M3 - */ -@Service("dependencyTreeBuilder#maven3") -public class Maven3DependencyTreeBuilder - implements DependencyTreeBuilder -{ - private Logger log = LoggerFactory.getLogger( Maven3DependencyTreeBuilder.class ); - - private MavenRepositorySystem mavenRepositorySystem; - - @Inject - @Named( "repositoryPathTranslator#maven2" ) - private RepositoryPathTranslator pathTranslator; - - @Inject - @Named("metadataReader#maven") - private MavenMetadataReader metadataReader; - - @Inject - private ProxyConnectorAdmin proxyConnectorAdmin; - - @Inject - private NetworkProxyAdmin networkProxyAdmin; - - @Inject - RepositoryRegistry repositoryRegistry; - - @Inject - MavenSystemManager mavenSystemManager; - - - @PostConstruct - public void initialize() - throws RuntimeException - { - try - { - mavenRepositorySystem = initMaven( ); - } - catch ( IllegalAccessException e ) - { - throw new RuntimeException( "Could not initialize maven" ); - } - } - - MavenRepositorySystem initMaven() throws IllegalAccessException - { - MavenRepositorySystem system = new MavenRepositorySystem( ); - DefaultArtifactHandlerManager afm = new DefaultArtifactHandlerManager( ); - DefaultRepositoryLayout layout = new DefaultRepositoryLayout( ); - FieldUtils.writeField( system, "artifactHandlerManager", afm, true); - Map map = new HashMap<>( ); - map.put( "defaultRepositoryLayout", layout ); - FieldUtils.writeField( system, "layouts", map, true); - return system; - } - - - - public void buildDependencyTree( List repositoryIds, String groupId, String artifactId, String version, - DependencyVisitor dependencyVisitor ) - throws DependencyTreeBuilderException - { - - Artifact projectArtifact = mavenRepositorySystem.createProjectArtifact(groupId, artifactId, version); - ManagedRepository repository = findArtifactInRepositories( repositoryIds, projectArtifact ); - - if ( repository == null ) - { - // metadata could not be resolved - log.info("Did not find repository with artifact {}/{}/{}", groupId, artifactId, version); - return; - } - - List remoteRepositories = new ArrayList<>(); - Map networkProxies = new HashMap<>(); - - try - { - // MRM-1411 - // TODO: this is a workaround for a lack of proxy capability in the resolvers - replace when it can all be - // handled there. It doesn't cache anything locally! - - Map> proxyConnectorsMap = proxyConnectorAdmin.getProxyConnectorAsMap(); - List proxyConnectors = proxyConnectorsMap.get( repository.getId() ); - if ( proxyConnectors != null ) - { - for ( ProxyConnector proxyConnector : proxyConnectors ) - { - remoteRepositories.add( - repositoryRegistry.getRemoteRepository( proxyConnector.getTargetRepoId() ) ); - - NetworkProxy networkProxyConfig = networkProxyAdmin.getNetworkProxy( proxyConnector.getProxyId() ); - - if ( networkProxyConfig != null ) - { - // key/value: remote repo ID/proxy info - networkProxies.put( proxyConnector.getTargetRepoId(), networkProxyConfig ); - } - } - } - } - catch ( RepositoryAdminException e ) - { - throw new DependencyTreeBuilderException( e.getMessage(), e ); - } - - // FIXME take care of relative path - ResolveRequest resolveRequest = new ResolveRequest(); - resolveRequest.dependencyVisitor = dependencyVisitor; - resolveRequest.localRepoDir = repository.getRoot().getFilePath().toAbsolutePath().toString(); - resolveRequest.groupId = groupId; - resolveRequest.artifactId = artifactId; - resolveRequest.version = version; - resolveRequest.remoteRepositories = remoteRepositories; - resolveRequest.networkProxies = networkProxies; - resolve( resolveRequest ); - } - - - @Override - public List buildDependencyTree( List repositoryIds, String groupId, String artifactId, - String version ) - throws DependencyTreeBuilderException - { - - List treeEntries = new ArrayList<>(); - TreeDependencyNodeVisitor treeDependencyNodeVisitor = new TreeDependencyNodeVisitor( treeEntries ); - - buildDependencyTree( repositoryIds, groupId, artifactId, version, treeDependencyNodeVisitor ); - - log.debug( "treeEntries: {}", treeEntries ); - return treeEntries; - } - - private static class ResolveRequest - { - String localRepoDir, groupId, artifactId, version; - - DependencyVisitor dependencyVisitor; - - List remoteRepositories; - - Map networkProxies; - - } - - - private void resolve( ResolveRequest resolveRequest ) - { - - RepositorySystem system = mavenSystemManager.getRepositorySystem(); - RepositorySystemSession session = MavenSystemManager.newRepositorySystemSession( resolveRequest.localRepoDir ); - - org.eclipse.aether.artifact.Artifact artifact = new DefaultArtifact( - resolveRequest.groupId + ":" + resolveRequest.artifactId + ":" + resolveRequest.version ); - - CollectRequest collectRequest = new CollectRequest(); - collectRequest.setRoot( new Dependency( artifact, "" ) ); - - // add remote repositories - for ( RemoteRepository remoteRepository : resolveRequest.remoteRepositories ) - { - org.eclipse.aether.repository.RemoteRepository repo = new org.eclipse.aether.repository.RemoteRepository.Builder( remoteRepository.getId( ), "default", remoteRepository.getLocation( ).toString() ).build( ); - collectRequest.addRepository(repo); - } - collectRequest.setRequestContext( "project" ); - - //collectRequest.addRepository( repo ); - - try - { - CollectResult collectResult = system.collectDependencies( session, collectRequest ); - collectResult.getRoot().accept( resolveRequest.dependencyVisitor ); - log.debug("Collected dependency results for resolve"); - } - catch ( DependencyCollectionException e ) - { - log.error( "Error while collecting dependencies (resolve): {}", e.getMessage(), e ); - } - - - - } - - private ManagedRepository findArtifactInRepositories( List repositoryIds, Artifact projectArtifact ) { - for ( String repoId : repositoryIds ) - { - ManagedRepository managedRepo = repositoryRegistry.getManagedRepository(repoId); - StorageAsset repoDir = managedRepo.getRoot(); - - StorageAsset file = pathTranslator.toFile( repoDir, projectArtifact.getGroupId(), projectArtifact.getArtifactId(), - projectArtifact.getBaseVersion(), - projectArtifact.getArtifactId() + "-" + projectArtifact.getVersion() - + ".pom" ); - - if ( file.exists() ) - { - return managedRepo; - } - // try with snapshot version - if ( StringUtils.endsWith( projectArtifact.getBaseVersion(), VersionUtil.SNAPSHOT ) ) - { - StorageAsset metadataFile = file.getParent().resolve( MetadataTools.MAVEN_METADATA ); - if ( metadataFile.exists() ) - { - try - { - ArchivaRepositoryMetadata archivaRepositoryMetadata = metadataReader.read( metadataFile); - int buildNumber = archivaRepositoryMetadata.getSnapshotVersion().getBuildNumber(); - String timeStamp = archivaRepositoryMetadata.getSnapshotVersion().getTimestamp(); - // rebuild file name with timestamped version and build number - String timeStampFileName = - new StringBuilder( projectArtifact.getArtifactId() ).append( '-' ).append( - StringUtils.remove( projectArtifact.getBaseVersion(), - "-" + VersionUtil.SNAPSHOT ) ).append( '-' ).append( - timeStamp ).append( '-' ).append( Integer.toString( buildNumber ) ).append( - ".pom" ).toString(); - StorageAsset timeStampFile = file.getParent().resolve( timeStampFileName ); - log.debug( "try to find timestamped snapshot version file: {}", timeStampFile); - if ( timeStampFile.exists() ) - { - return managedRepo; - } - } - catch ( RepositoryMetadataException e ) - { - log.warn( "skip fail to find timestamped snapshot pom: {}", e.getMessage() ); - } - } - } - } - return null; - } - -} diff --git a/archiva-modules/archiva-maven/archiva-maven-repository/src/main/java/org/apache/archiva/repository/maven/dependency/tree/TreeDependencyNodeVisitor.java b/archiva-modules/archiva-maven/archiva-maven-repository/src/main/java/org/apache/archiva/repository/maven/dependency/tree/TreeDependencyNodeVisitor.java deleted file mode 100644 index 3cc69bdb7..000000000 --- a/archiva-modules/archiva-maven/archiva-maven-repository/src/main/java/org/apache/archiva/repository/maven/dependency/tree/TreeDependencyNodeVisitor.java +++ /dev/null @@ -1,92 +0,0 @@ -package org.apache.archiva.repository.maven.dependency.tree; -/* - * 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.maven.model.Artifact; -import org.apache.archiva.maven.model.TreeEntry; -import org.eclipse.aether.graph.DependencyNode; -import org.eclipse.aether.graph.DependencyVisitor; -import org.modelmapper.ModelMapper; -import org.modelmapper.convention.MatchingStrategies; - -import java.util.List; - -/** - * @author Olivier Lamy - * @since 1.4-M3 - */ -public class TreeDependencyNodeVisitor - implements DependencyVisitor -{ - - final List treeEntries; - - private TreeEntry currentEntry; - - private org.eclipse.aether.graph.DependencyNode firstDependencyNode; - - public TreeDependencyNodeVisitor( List treeEntries ) - { - this.treeEntries = treeEntries; - } - - - @Override - public boolean visitEnter( DependencyNode dependencyNode ) - { - TreeEntry entry = - new TreeEntry( getModelMapper().map( dependencyNode.getDependency().getArtifact(), Artifact.class ) ); - entry.getArtifact().setFileExtension( dependencyNode.getDependency().getArtifact().getExtension() ); - entry.getArtifact().setScope( dependencyNode.getDependency().getScope() ); - entry.setParent( currentEntry ); - currentEntry = entry; - - if ( firstDependencyNode == null ) - { - firstDependencyNode = dependencyNode; - treeEntries.add( currentEntry ); - } - else - { - currentEntry.getParent().getChilds().add( currentEntry ); - } - return true; - } - - @Override - public boolean visitLeave( DependencyNode dependencyNode ) - { - currentEntry = currentEntry.getParent(); - return true; - } - - private static class ModelMapperHolder - { - private static ModelMapper MODEL_MAPPER = new ModelMapper(); - - static - { - MODEL_MAPPER.getConfiguration().setMatchingStrategy( MatchingStrategies.STRICT ); - } - } - - protected ModelMapper getModelMapper() - { - return ModelMapperHolder.MODEL_MAPPER; - } -} diff --git a/archiva-modules/archiva-maven/archiva-maven-repository/src/main/java/org/apache/archiva/repository/maven/merge/Maven2RepositoryMerger.java b/archiva-modules/archiva-maven/archiva-maven-repository/src/main/java/org/apache/archiva/repository/maven/merge/Maven2RepositoryMerger.java deleted file mode 100644 index 1f21f6ffa..000000000 --- a/archiva-modules/archiva-maven/archiva-maven-repository/src/main/java/org/apache/archiva/repository/maven/merge/Maven2RepositoryMerger.java +++ /dev/null @@ -1,440 +0,0 @@ -package org.apache.archiva.repository.maven.merge; - -/* - * 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.filelock.DefaultFileLockManager; -import org.apache.archiva.common.utils.VersionComparator; -import org.apache.archiva.common.utils.VersionUtil; -import org.apache.archiva.configuration.ArchivaConfiguration; -import org.apache.archiva.configuration.Configuration; -import org.apache.archiva.configuration.ManagedRepositoryConfiguration; -import org.apache.archiva.filter.Filter; -import org.apache.archiva.maven.metadata.MavenMetadataReader; -import org.apache.archiva.metadata.model.ArtifactMetadata; -import org.apache.archiva.metadata.repository.MetadataRepository; -import org.apache.archiva.metadata.repository.MetadataRepositoryException; -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.model.ArchivaRepositoryMetadata; -import org.apache.archiva.repository.RepositoryException; -import org.apache.archiva.repository.RepositoryType; -import org.apache.archiva.repository.metadata.RepositoryMetadataException; -import org.apache.archiva.repository.metadata.base.RepositoryMetadataWriter; -import org.apache.archiva.repository.storage.StorageAsset; -import org.apache.archiva.repository.storage.fs.FilesystemAsset; -import org.apache.archiva.repository.storage.fs.FilesystemStorage; -import org.apache.archiva.stagerepository.merge.RepositoryMerger; -import org.apache.archiva.stagerepository.merge.RepositoryMergerException; -import org.apache.commons.io.FileUtils; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.stereotype.Service; - -import javax.inject.Inject; -import javax.inject.Named; -import java.io.BufferedWriter; -import java.io.IOException; -import java.nio.file.Files; -import java.nio.file.Path; -import java.nio.file.Paths; -import java.text.DateFormat; -import java.text.SimpleDateFormat; -import java.util.ArrayList; -import java.util.Calendar; -import java.util.Collections; -import java.util.Comparator; -import java.util.Date; -import java.util.List; -import java.util.TimeZone; -import java.util.TreeSet; - -/** - * - */ -@Service ("repositoryMerger#maven2") -public class Maven2RepositoryMerger - implements RepositoryMerger -{ - - @Inject - @Named("metadataReader#maven") - private MavenMetadataReader metadataReader; - - private static final Logger log = LoggerFactory.getLogger( Maven2RepositoryMerger.class ); - - private static final Comparator META_COMPARATOR = Comparator.comparing(ArtifactMetadata::getNamespace) - .thenComparing(ArtifactMetadata::getProject) - .thenComparing(ArtifactMetadata::getId) - .thenComparing(ArtifactMetadata::getVersion); - - /** - * - */ - private ArchivaConfiguration configuration; - - /** - * - */ - private RepositoryPathTranslator pathTranslator; - - private static final String METADATA_FILENAME = "maven-metadata.xml"; - - @Inject - private RepositorySessionFactory repositorySessionFactory; - - @Inject - public Maven2RepositoryMerger( - @Named (value = "archivaConfiguration#default") ArchivaConfiguration archivaConfiguration, - @Named (value = "repositoryPathTranslator#maven2") RepositoryPathTranslator repositoryPathTranslator ) - { - this.configuration = archivaConfiguration; - this.pathTranslator = repositoryPathTranslator; - } - - public void setConfiguration( ArchivaConfiguration configuration ) - { - this.configuration = configuration; - } - - @Override - public boolean supportsRepository( RepositoryType type ) - { - return RepositoryType.MAVEN.equals( type ); - } - - @Override - public void merge( MetadataRepository metadataRepository, String sourceRepoId, String targetRepoId ) - throws RepositoryMergerException - { - - try(RepositorySession session = repositorySessionFactory.createSession()) - { - List artifactsInSourceRepo = metadataRepository.getArtifacts(session , sourceRepoId ); - for ( ArtifactMetadata artifactMetadata : artifactsInSourceRepo ) - { - artifactMetadata.setRepositoryId( targetRepoId ); - createFolderStructure( sourceRepoId, targetRepoId, artifactMetadata ); - } - } - catch ( MetadataRepositoryException e ) - { - throw new RepositoryMergerException( e.getMessage(), e ); - } - catch ( IOException e ) - { - throw new RepositoryMergerException( e.getMessage(), e ); - } - catch ( RepositoryException e ) - { - throw new RepositoryMergerException( e.getMessage(), e ); - } - } - - // TODO when UI needs a subset to merge - @Override - public void merge( MetadataRepository metadataRepository, String sourceRepoId, String targetRepoId, - Filter filter ) - throws RepositoryMergerException - { - try(RepositorySession session = repositorySessionFactory.createSession()) - { - List sourceArtifacts = metadataRepository.getArtifacts(session , sourceRepoId ); - for ( ArtifactMetadata metadata : sourceArtifacts ) - { - if ( filter.accept( metadata ) ) - { - createFolderStructure( sourceRepoId, targetRepoId, metadata ); - } - } - } - catch ( MetadataRepositoryException e ) - { - throw new RepositoryMergerException( e.getMessage(), e ); - } - catch ( IOException e ) - { - throw new RepositoryMergerException( e.getMessage(), e ); - } - catch ( RepositoryException e ) - { - throw new RepositoryMergerException( e.getMessage(), e ); - } - } - - private void createFolderStructure( String sourceRepoId, String targetRepoId, ArtifactMetadata artifactMetadata ) - throws IOException, RepositoryException - { - Configuration config = configuration.getConfiguration(); - - ManagedRepositoryConfiguration targetRepoConfig = config.findManagedRepositoryById( targetRepoId ); - - ManagedRepositoryConfiguration sourceRepoConfig = config.findManagedRepositoryById( sourceRepoId ); - - Date lastUpdatedTimestamp = Calendar.getInstance().getTime(); - - TimeZone timezone = TimeZone.getTimeZone( "UTC" ); - - DateFormat fmt = new SimpleDateFormat( "yyyyMMdd.HHmmss" ); - - fmt.setTimeZone( timezone ); - - String timestamp = fmt.format( lastUpdatedTimestamp ); - - String targetRepoPath = targetRepoConfig.getLocation(); - - String sourceRepoPath = sourceRepoConfig.getLocation(); - - String artifactPath = pathTranslator.toPath( artifactMetadata.getNamespace(), artifactMetadata.getProject(), - artifactMetadata.getProjectVersion(), artifactMetadata.getId() ); - - Path sourceArtifactFile = Paths.get( sourceRepoPath, artifactPath ); - - Path targetArtifactFile = Paths.get( targetRepoPath, artifactPath ); - - log.debug( "artifactPath {}", artifactPath ); - - int lastIndex = artifactPath.lastIndexOf( RepositoryPathTranslator.PATH_SEPARATOR ); - - Path targetFile = Paths.get( targetRepoPath, artifactPath.substring( 0, lastIndex ) ); - - if ( !Files.exists(targetFile) ) - { - // create the folder structure when it does not exist - Files.createDirectories(targetFile); - } - // artifact copying - copyFile( sourceArtifactFile, targetArtifactFile ); - - // pom file copying - // TODO need to use path translator to get the pom file path -// String fileName = artifactMetadata.getProject() + "-" + artifactMetadata.getVersion() + ".pom"; -// -// File sourcePomFile = -// pathTranslator.toFile( new File( sourceRepoPath ), artifactMetadata.getId(), artifactMetadata.getProject(), -// artifactMetadata.getVersion(), fileName ); -// -// String relativePathToPomFile = sourcePomFile.getAbsolutePath().split( sourceRepoPath )[1]; -// File targetPomFile = new File( targetRepoPath, relativePathToPomFile ); - - //pom file copying (file path is taken with out using path translator) - - String index = artifactPath.substring( lastIndex + 1 ); - int last = index.lastIndexOf( '.' ); - Path sourcePomFile = Paths.get( sourceRepoPath, - artifactPath.substring( 0, lastIndex ) + "/" + artifactPath.substring( - lastIndex + 1 ).substring( 0, last ) + ".pom" ); - Path targetPomFile = Paths.get( targetRepoPath, - artifactPath.substring( 0, lastIndex ) + "/" + artifactPath.substring( - lastIndex + 1 ).substring( 0, last ) + ".pom" ); - - if ( !Files.exists(targetPomFile) && Files.exists(sourcePomFile) ) - { - copyFile( sourcePomFile, targetPomFile ); - } - - // explicitly update only if metadata-updater consumer is not enabled! - if ( !config.getRepositoryScanning().getKnownContentConsumers().contains( "metadata-updater" ) ) - { - - // updating version metadata files - FilesystemStorage fsStorage = new FilesystemStorage(Paths.get(sourceRepoPath), new DefaultFileLockManager()); - - StorageAsset versionMetaDataFileInSourceRepo = - pathTranslator.toFile( new FilesystemAsset(fsStorage, "", Paths.get(sourceRepoPath)), artifactMetadata.getNamespace(), - artifactMetadata.getProject(), artifactMetadata.getVersion(), - METADATA_FILENAME ); - - if ( versionMetaDataFileInSourceRepo.exists() ) - {//Pattern quote for windows path - String relativePathToVersionMetadataFile = - getRelativeAssetPath(versionMetaDataFileInSourceRepo); - Path versionMetaDataFileInTargetRepo = Paths.get( targetRepoPath, relativePathToVersionMetadataFile ); - - if ( !Files.exists(versionMetaDataFileInTargetRepo) ) - { - copyFile( versionMetaDataFileInSourceRepo.getFilePath(), versionMetaDataFileInTargetRepo ); - } - else - { - updateVersionMetadata( versionMetaDataFileInTargetRepo, artifactMetadata, lastUpdatedTimestamp ); - - } - } - - // updating project meta data file - StorageAsset projectDirectoryInSourceRepo = versionMetaDataFileInSourceRepo.getParent().getParent(); - StorageAsset projectMetadataFileInSourceRepo = projectDirectoryInSourceRepo.resolve(METADATA_FILENAME ); - - if ( projectMetadataFileInSourceRepo.exists() ) - { - String relativePathToProjectMetadataFile = - getRelativeAssetPath(projectMetadataFileInSourceRepo); - Path projectMetadataFileInTargetRepo = Paths.get( targetRepoPath, relativePathToProjectMetadataFile ); - - if ( !Files.exists(projectMetadataFileInTargetRepo) ) - { - - copyFile( projectMetadataFileInSourceRepo.getFilePath(), projectMetadataFileInTargetRepo ); - } - else - { - updateProjectMetadata( projectMetadataFileInTargetRepo, artifactMetadata, lastUpdatedTimestamp, - timestamp ); - } - } - } - - } - - private String getRelativeAssetPath(final StorageAsset asset) { - String relPath = asset.getPath(); - while(relPath.startsWith("/")) { - relPath = relPath.substring(1); - } - return relPath; - } - - private void copyFile( Path sourceFile, Path targetFile ) - throws IOException - { - - FileUtils.copyFile( sourceFile.toFile(), targetFile.toFile() ); - - } - - private void updateProjectMetadata( Path projectMetaDataFileIntargetRepo, ArtifactMetadata artifactMetadata, - Date lastUpdatedTimestamp, String timestamp ) - throws RepositoryMetadataException - { - ArrayList availableVersions = new ArrayList<>(); - String latestVersion = artifactMetadata.getProjectVersion(); - - ArchivaRepositoryMetadata projectMetadata = getMetadata( projectMetaDataFileIntargetRepo ); - - if ( Files.exists(projectMetaDataFileIntargetRepo) ) - { - availableVersions = (ArrayList) projectMetadata.getAvailableVersions(); - - Collections.sort( availableVersions, VersionComparator.getInstance() ); - - if ( !availableVersions.contains( artifactMetadata.getVersion() ) ) - { - availableVersions.add( artifactMetadata.getVersion() ); - } - - latestVersion = availableVersions.get( availableVersions.size() - 1 ); - } - else - { - availableVersions.add( artifactMetadata.getProjectVersion() ); - projectMetadata.setGroupId( artifactMetadata.getNamespace() ); - projectMetadata.setArtifactId( artifactMetadata.getProject() ); - } - - if ( projectMetadata.getGroupId() == null ) - { - projectMetadata.setGroupId( artifactMetadata.getNamespace() ); - } - - if ( projectMetadata.getArtifactId() == null ) - { - projectMetadata.setArtifactId( artifactMetadata.getProject() ); - } - - projectMetadata.setLatestVersion( latestVersion ); - projectMetadata.setAvailableVersions( availableVersions ); - projectMetadata.setLastUpdated( timestamp ); - projectMetadata.setLastUpdatedTimestamp( lastUpdatedTimestamp ); - - if ( !VersionUtil.isSnapshot( artifactMetadata.getVersion() ) ) - { - projectMetadata.setReleasedVersion( latestVersion ); - } - - try(BufferedWriter writer = Files.newBufferedWriter(projectMetaDataFileIntargetRepo)) { - RepositoryMetadataWriter.write( projectMetadata, writer ); - } catch (IOException e) { - throw new RepositoryMetadataException(e); - } - - } - - private void updateVersionMetadata( Path versionMetaDataFileInTargetRepo, ArtifactMetadata artifactMetadata, - Date lastUpdatedTimestamp ) - throws RepositoryMetadataException - { - ArchivaRepositoryMetadata versionMetadata = getMetadata( versionMetaDataFileInTargetRepo ); - if ( !Files.exists(versionMetaDataFileInTargetRepo) ) - { - versionMetadata.setGroupId( artifactMetadata.getNamespace() ); - versionMetadata.setArtifactId( artifactMetadata.getProject() ); - versionMetadata.setVersion( artifactMetadata.getProjectVersion() ); - } - - versionMetadata.setLastUpdatedTimestamp( lastUpdatedTimestamp ); - try(BufferedWriter writer = Files.newBufferedWriter(versionMetaDataFileInTargetRepo) ) { - RepositoryMetadataWriter.write( versionMetadata, writer); - } catch (IOException e) { - throw new RepositoryMetadataException(e); - } - } - - private ArchivaRepositoryMetadata getMetadata( Path metadataFile ) - throws RepositoryMetadataException - { - ArchivaRepositoryMetadata metadata = new ArchivaRepositoryMetadata(); - if ( Files.exists(metadataFile) ) - { - metadata = metadataReader.read( metadataFile ); - } - return metadata; - } - - @Override - public List getConflictingArtifacts( MetadataRepository metadataRepository, String sourceRepo, - String targetRepo ) - throws RepositoryMergerException - { - try(RepositorySession session = repositorySessionFactory.createSession()) - { - TreeSet targetArtifacts = new TreeSet<>(META_COMPARATOR); - targetArtifacts.addAll(metadataRepository.getArtifacts(session , targetRepo )); - TreeSet sourceArtifacts = new TreeSet<>(META_COMPARATOR); - sourceArtifacts.addAll(metadataRepository.getArtifacts(session , sourceRepo )); - sourceArtifacts.retainAll(targetArtifacts); - - return new ArrayList<>(sourceArtifacts); - } - catch ( MetadataRepositoryException e ) - { - throw new RepositoryMergerException( e.getMessage(), e ); - } - } - - public RepositorySessionFactory getRepositorySessionFactory( ) - { - return repositorySessionFactory; - } - - public void setRepositorySessionFactory( RepositorySessionFactory repositorySessionFactory ) - { - this.repositorySessionFactory = repositorySessionFactory; - } -} diff --git a/archiva-modules/archiva-maven/archiva-maven-repository/src/main/java/org/apache/archiva/repository/maven/metadata/storage/ArtifactMappingProvider.java b/archiva-modules/archiva-maven/archiva-maven-repository/src/main/java/org/apache/archiva/repository/maven/metadata/storage/ArtifactMappingProvider.java deleted file mode 100644 index 96ace1c76..000000000 --- a/archiva-modules/archiva-maven/archiva-maven-repository/src/main/java/org/apache/archiva/repository/maven/metadata/storage/ArtifactMappingProvider.java +++ /dev/null @@ -1,26 +0,0 @@ -package org.apache.archiva.repository.maven.metadata.storage; - -/* - * 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. - */ - -public interface ArtifactMappingProvider -{ - String mapClassifierAndExtensionToType( String classifier, String ext ); - - String mapTypeToExtension( String type ); -} diff --git a/archiva-modules/archiva-maven/archiva-maven-repository/src/main/java/org/apache/archiva/repository/maven/metadata/storage/ArtifactMetadataVersionComparator.java b/archiva-modules/archiva-maven/archiva-maven-repository/src/main/java/org/apache/archiva/repository/maven/metadata/storage/ArtifactMetadataVersionComparator.java deleted file mode 100644 index d8e044ee7..000000000 --- a/archiva-modules/archiva-maven/archiva-maven-repository/src/main/java/org/apache/archiva/repository/maven/metadata/storage/ArtifactMetadataVersionComparator.java +++ /dev/null @@ -1,42 +0,0 @@ -package org.apache.archiva.repository.maven.metadata.storage; -/* - * 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.metadata.model.ArtifactMetadata; -import org.apache.maven.artifact.versioning.DefaultArtifactVersion; - -import java.util.Comparator; - -/** - * @author Olivier Lamy - * @since 1.4-M3 - */ -public class ArtifactMetadataVersionComparator - implements Comparator -{ - public static ArtifactMetadataVersionComparator INSTANCE = new ArtifactMetadataVersionComparator(); - - @Override - public int compare( ArtifactMetadata o1, ArtifactMetadata o2 ) - { - // sort by version (reverse), then ID - int result = - new DefaultArtifactVersion( o2.getVersion() ).compareTo( new DefaultArtifactVersion( o1.getVersion() ) ); - return result != 0 ? result : o1.getId().compareTo( o2.getId() ); - } -} diff --git a/archiva-modules/archiva-maven/archiva-maven-repository/src/main/java/org/apache/archiva/repository/maven/metadata/storage/DefaultArtifactMappingProvider.java b/archiva-modules/archiva-maven/archiva-maven-repository/src/main/java/org/apache/archiva/repository/maven/metadata/storage/DefaultArtifactMappingProvider.java deleted file mode 100644 index a0c51ef74..000000000 --- a/archiva-modules/archiva-maven/archiva-maven-repository/src/main/java/org/apache/archiva/repository/maven/metadata/storage/DefaultArtifactMappingProvider.java +++ /dev/null @@ -1,89 +0,0 @@ -package org.apache.archiva.repository.maven.metadata.storage; - -/* - * 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.springframework.stereotype.Service; - -import java.util.HashMap; -import java.util.Map; - -/** - * - */ -@Service( "artifactMappingProvider#default" ) -public class DefaultArtifactMappingProvider - implements ArtifactMappingProvider -{ - private final Map classifierAndExtensionToTypeMap; - - private final Map typeToExtensionMap; - - public DefaultArtifactMappingProvider() - { - classifierAndExtensionToTypeMap = new HashMap<>( 4 ); - - // Maven 2.2.1 supplied types (excluding defaults where extension == type and no classifier) - classifierAndExtensionToTypeMap.put( "client:jar", "ejb-client" ); - classifierAndExtensionToTypeMap.put( "sources:jar", "java-source" ); - classifierAndExtensionToTypeMap.put( "javadoc:jar", "javadoc" ); - classifierAndExtensionToTypeMap.put( "tests:jar", "test-jar" ); - - typeToExtensionMap = new HashMap<>(); - - // Maven 2.2.1 supplied types (excluding defaults where extension == type and no classifier) - typeToExtensionMap.put( "ejb-client", "jar" ); - typeToExtensionMap.put( "ejb", "jar" ); - typeToExtensionMap.put( "java-source", "jar" ); - typeToExtensionMap.put( "javadoc", "jar" ); - typeToExtensionMap.put( "test-jar", "jar" ); - typeToExtensionMap.put( "maven-plugin", "jar" ); - - // Additional type - typeToExtensionMap.put( "maven-archetype", "jar" ); - - // TODO: move to maven 1 plugin - but note that it won't have the interface type and might need to reproduce the - // same thing - typeToExtensionMap.put( "maven-one-plugin", "jar" ); - typeToExtensionMap.put( "javadoc.jar", "jar" ); - typeToExtensionMap.put( "uberjar", "jar" ); - typeToExtensionMap.put( "distribution-tgz", "tar.gz" ); - typeToExtensionMap.put( "distribution-zip", "zip" ); - typeToExtensionMap.put( "aspect", "jar" ); - } - - @Override - public String mapClassifierAndExtensionToType( String classifier, String ext ) - { - if ( classifier == null ) - { - classifier = ""; - } - if ( ext == null ) - { - ext = ""; - } - return classifierAndExtensionToTypeMap.get( classifier + ":" + ext ); - } - - @Override - public String mapTypeToExtension( String type ) - { - return typeToExtensionMap.get( type ); - } -} diff --git a/archiva-modules/archiva-maven/archiva-maven-repository/src/main/java/org/apache/archiva/repository/maven/metadata/storage/DummyLifecycleBindingsInjector.java b/archiva-modules/archiva-maven/archiva-maven-repository/src/main/java/org/apache/archiva/repository/maven/metadata/storage/DummyLifecycleBindingsInjector.java deleted file mode 100644 index a398d5e64..000000000 --- a/archiva-modules/archiva-maven/archiva-maven-repository/src/main/java/org/apache/archiva/repository/maven/metadata/storage/DummyLifecycleBindingsInjector.java +++ /dev/null @@ -1,39 +0,0 @@ -package org.apache.archiva.repository.maven.metadata.storage; - -/* - * 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.model.Model; -import org.apache.maven.model.building.ModelBuildingRequest; -import org.apache.maven.model.building.ModelProblemCollector; -import org.apache.maven.model.plugin.LifecycleBindingsInjector; - -/** - * Required as plexus-spring doesn't understand the optional = true argument added to Plexus and used here. - * - * - */ -public class DummyLifecycleBindingsInjector - implements LifecycleBindingsInjector -{ - @Override - public void injectLifecycleBindings( Model model, ModelBuildingRequest modelBuildingRequest, ModelProblemCollector modelProblemCollector ) - { - // left intentionally blank - } -} diff --git a/archiva-modules/archiva-maven/archiva-maven-repository/src/main/java/org/apache/archiva/repository/maven/metadata/storage/Maven2RepositoryPathTranslator.java b/archiva-modules/archiva-maven/archiva-maven-repository/src/main/java/org/apache/archiva/repository/maven/metadata/storage/Maven2RepositoryPathTranslator.java deleted file mode 100644 index 91c62bd7e..000000000 --- a/archiva-modules/archiva-maven/archiva-maven-repository/src/main/java/org/apache/archiva/repository/maven/metadata/storage/Maven2RepositoryPathTranslator.java +++ /dev/null @@ -1,362 +0,0 @@ -package org.apache.archiva.repository.maven.metadata.storage; - -/* - * 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.utils.VersionUtil; -import org.apache.archiva.maven.metadata.model.MavenArtifactFacet; -import org.apache.archiva.metadata.model.ArtifactMetadata; -import org.apache.archiva.metadata.repository.storage.RepositoryPathTranslator; -import org.apache.archiva.repository.storage.StorageAsset; -import org.apache.commons.lang3.StringUtils; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.stereotype.Service; - -import javax.annotation.PostConstruct; -import javax.inject.Inject; -import java.util.List; -import java.util.regex.Matcher; -import java.util.regex.Pattern; - -/** - * - */ -@Service( "repositoryPathTranslator#maven2" ) -public class Maven2RepositoryPathTranslator - implements RepositoryPathTranslator -{ - - private static final Logger log = LoggerFactory.getLogger( Maven2RepositoryPathTranslator.class ); - - private static final char GROUP_SEPARATOR = '.'; - - private static final Pattern TIMESTAMP_PATTERN = Pattern.compile( "([0-9]{8}.[0-9]{6})-([0-9]+).*" ); - - - private static final Pattern MAVEN_PLUGIN_PATTERN = Pattern.compile( "^(maven-.*-plugin)|(.*-maven-plugin)$" ); - - /** - * - * see #initialize - */ - @Inject - private List artifactMappingProviders; - - public Maven2RepositoryPathTranslator() - { - // noop - } - - - public List getArtifactMappingProviders( ) - { - return artifactMappingProviders; - } - - public void setArtifactMappingProviders( List artifactMappingProviders ) - { - this.artifactMappingProviders = artifactMappingProviders; - } - - - @PostConstruct - public void initialize() - { - //artifactMappingProviders = new ArrayList( - // applicationContext.getBeansOfType( ArtifactMappingProvider.class ).values() ); - - } - - - public Maven2RepositoryPathTranslator( List artifactMappingProviders ) - { - this.artifactMappingProviders = artifactMappingProviders; - } - - @Override - public StorageAsset toFile(StorageAsset basedir, String namespace, String projectId, String projectVersion, String filename ) - { - return basedir.resolve( toPath( namespace, projectId, projectVersion, filename ) ); - } - - @Override - public StorageAsset toFile( StorageAsset basedir, String namespace, String projectId, String projectVersion ) - { - return basedir.resolve( toPath( namespace, projectId, projectVersion ) ); - } - - @Override - public String toPath( String namespace, String projectId, String projectVersion, String filename ) - { - StringBuilder path = new StringBuilder(); - - appendNamespaceToProjectVersion( path, namespace, projectId, projectVersion ); - path.append( PATH_SEPARATOR ); - path.append( filename ); - - return path.toString(); - } - - private void appendNamespaceToProjectVersion( StringBuilder path, String namespace, String projectId, - String projectVersion ) - { - appendNamespaceAndProject( path, namespace, projectId ); - path.append( projectVersion ); - } - - public String toPath( String namespace, String projectId, String projectVersion ) - { - StringBuilder path = new StringBuilder(); - - appendNamespaceToProjectVersion( path, namespace, projectId, projectVersion ); - - return path.toString(); - } - - public String toPath( String namespace ) - { - StringBuilder path = new StringBuilder(); - - appendNamespace( path, namespace ); - - return path.toString(); - } - - @Override - public String toPath( String namespace, String projectId ) - { - StringBuilder path = new StringBuilder(); - - appendNamespaceAndProject( path, namespace, projectId ); - - return path.toString(); - } - - private void appendNamespaceAndProject( StringBuilder path, String namespace, String projectId ) - { - appendNamespace( path, namespace ); - if (StringUtils.isNotEmpty( projectId )) - { - path.append( projectId ).append( PATH_SEPARATOR ); - } - } - - private void appendNamespace( StringBuilder path, String namespace ) - { - if ( StringUtils.isNotEmpty( namespace ) ) { - path.append( formatAsDirectory( namespace ) ).append( PATH_SEPARATOR ); - } - } - - @Override - public StorageAsset toFile( StorageAsset basedir, String namespace, String projectId ) - { - return basedir.resolve( toPath( namespace, projectId ) ); - } - - @Override - public StorageAsset toFile( StorageAsset basedir, String namespace ) - { - return basedir.resolve( toPath( namespace ) ); - } - - private String formatAsDirectory( String directory ) - { - return directory.replace( GROUP_SEPARATOR, PATH_SEPARATOR ); - } - - @Override - public ArtifactMetadata getArtifactForPath( String repoId, String relativePath ) - { - String[] parts = relativePath.replace( '\\', '/' ).split( "/" ); - - int len = parts.length; - if ( len < 4 ) - { - throw new IllegalArgumentException( - "Not a valid artifact path in a Maven 2 repository, not enough directories: " + relativePath ); - } - - String id = parts[--len]; - String baseVersion = parts[--len]; - String artifactId = parts[--len]; - StringBuilder groupIdBuilder = new StringBuilder(); - for ( int i = 0; i < len - 1; i++ ) - { - groupIdBuilder.append( parts[i] ); - groupIdBuilder.append( '.' ); - } - groupIdBuilder.append( parts[len - 1] ); - - return getArtifactFromId( repoId, groupIdBuilder.toString(), artifactId, baseVersion, id ); - } - - @Override - public ArtifactMetadata getArtifactFromId( String repoId, String namespace, String projectId, String projectVersion, - String id ) - { - if ( !id.startsWith( projectId + "-" ) ) - { - throw new IllegalArgumentException( "Not a valid artifact path in a Maven 2 repository, filename '" + id - + "' doesn't start with artifact ID '" + projectId + "'" ); - } - - MavenArtifactFacet facet = new MavenArtifactFacet(); - - int index = projectId.length() + 1; - String version; - String idSubStrFromVersion = id.substring( index ); - if ( idSubStrFromVersion.startsWith( projectVersion ) && !VersionUtil.isUniqueSnapshot( projectVersion ) ) - { - // non-snapshot versions, or non-timestamped snapshot versions - version = projectVersion; - } - else if ( VersionUtil.isGenericSnapshot( projectVersion ) ) - { - // timestamped snapshots - try - { - int mainVersionLength = projectVersion.length() - 8; // 8 is length of "SNAPSHOT" - if ( mainVersionLength == 0 ) - { - throw new IllegalArgumentException( - "Timestamped snapshots must contain the main version, filename was '" + id + "'" ); - } - - Matcher m = TIMESTAMP_PATTERN.matcher( idSubStrFromVersion.substring( mainVersionLength ) ); - m.matches(); - String timestamp = m.group( 1 ); - String buildNumber = m.group( 2 ); - facet.setTimestamp( timestamp ); - facet.setBuildNumber( Integer.parseInt( buildNumber ) ); - version = idSubStrFromVersion.substring( 0, mainVersionLength ) + timestamp + "-" + buildNumber; - } - catch ( IllegalStateException e ) - { - throw new IllegalArgumentException( "Not a valid artifact path in a Maven 2 repository, filename '" + id - + "' doesn't contain a timestamped version matching snapshot '" - + projectVersion + "'", e); - } - } - else - { - // invalid - throw new IllegalArgumentException( - "Not a valid artifact path in a Maven 2 repository, filename '" + id + "' doesn't contain version '" - + projectVersion + "'" ); - } - - String classifier; - String ext; - index += version.length(); - if ( index == id.length() ) - { - // no classifier or extension - classifier = null; - ext = null; - } - else - { - char c = id.charAt( index ); - if ( c == '-' ) - { - // classifier up until '.' - int extIndex = id.indexOf( '.', index ); - if ( extIndex >= 0 ) - { - classifier = id.substring( index + 1, extIndex ); - ext = id.substring( extIndex + 1 ); - } - else - { - classifier = id.substring( index + 1 ); - ext = null; - } - } - else if ( c == '.' ) - { - // rest is the extension - classifier = null; - ext = id.substring( index + 1 ); - } - else - { - throw new IllegalArgumentException( "Not a valid artifact path in a Maven 2 repository, filename '" + id - + "' expected classifier or extension but got '" - + id.substring( index ) + "'" ); - } - } - - ArtifactMetadata metadata = new ArtifactMetadata(); - metadata.setId( id ); - metadata.setNamespace( namespace ); - metadata.setProject( projectId ); - metadata.setRepositoryId( repoId ); - metadata.setProjectVersion( projectVersion ); - metadata.setVersion( version ); - - facet.setClassifier( classifier ); - - // we use our own provider here instead of directly accessing Maven's artifact handlers as it has no way - // to select the correct order to apply multiple extensions mappings to a preferred type - // TODO: this won't allow the user to decide order to apply them if there are conflicts or desired changes - - // perhaps the plugins could register missing entries in configuration, then we just use configuration - // here? - - String type = null; - for ( ArtifactMappingProvider mapping : artifactMappingProviders ) - { - type = mapping.mapClassifierAndExtensionToType( classifier, ext ); - if ( type != null ) - { - break; - } - } - - // TODO: this is cheating! We should check the POM metadata instead - if ( type == null && "jar".equals( ext ) && isArtifactIdValidMavenPlugin( projectId ) ) - { - type = "maven-plugin"; - } - - // use extension as default - if ( type == null ) - { - type = ext; - } - - // TODO: should we allow this instead? - if ( type == null ) - { - throw new IllegalArgumentException( - "Not a valid artifact path in a Maven 2 repository, filename '" + id + "' does not have a type" ); - } - - facet.setType( type ); - metadata.addFacet( facet ); - - return metadata; - } - - - public boolean isArtifactIdValidMavenPlugin( String artifactId ) - { - return MAVEN_PLUGIN_PATTERN.matcher( artifactId ).matches(); - } -} diff --git a/archiva-modules/archiva-maven/archiva-maven-repository/src/main/java/org/apache/archiva/repository/maven/metadata/storage/Maven2RepositoryStorage.java b/archiva-modules/archiva-maven/archiva-maven-repository/src/main/java/org/apache/archiva/repository/maven/metadata/storage/Maven2RepositoryStorage.java deleted file mode 100644 index 27f52f2a8..000000000 --- a/archiva-modules/archiva-maven/archiva-maven-repository/src/main/java/org/apache/archiva/repository/maven/metadata/storage/Maven2RepositoryStorage.java +++ /dev/null @@ -1,994 +0,0 @@ -package org.apache.archiva.repository.maven.metadata.storage; - -/* - * 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.checksum.ChecksumAlgorithm; -import org.apache.archiva.checksum.ChecksummedFile; -import org.apache.archiva.common.Try; -import org.apache.archiva.common.utils.VersionUtil; -import org.apache.archiva.filter.Filter; -import org.apache.archiva.maven.metadata.MavenMetadataReader; -import org.apache.archiva.metadata.model.ArtifactMetadata; -import org.apache.archiva.metadata.model.ProjectMetadata; -import org.apache.archiva.metadata.model.ProjectVersionMetadata; -import org.apache.archiva.metadata.model.facets.RepositoryProblemFacet; -import org.apache.archiva.metadata.repository.storage.ReadMetadataRequest; -import org.apache.archiva.metadata.repository.storage.RelocationException; -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.metadata.repository.storage.RepositoryStorageRuntimeException; -import org.apache.archiva.model.ArchivaRepositoryMetadata; -import org.apache.archiva.model.SnapshotVersion; -import org.apache.archiva.policies.ProxyDownloadException; -import org.apache.archiva.proxy.ProxyRegistry; -import org.apache.archiva.maven.common.proxy.WagonFactory; -import org.apache.archiva.proxy.model.NetworkProxy; -import org.apache.archiva.proxy.model.ProxyConnector; -import org.apache.archiva.proxy.model.RepositoryProxyHandler; -import org.apache.archiva.repository.ManagedRepository; -import org.apache.archiva.repository.ManagedRepositoryContent; -import org.apache.archiva.repository.ReleaseScheme; -import org.apache.archiva.repository.RemoteRepository; -import org.apache.archiva.repository.RepositoryRegistry; -import org.apache.archiva.repository.RepositoryType; -import org.apache.archiva.repository.content.Artifact; -import org.apache.archiva.repository.content.BaseRepositoryContentLayout; -import org.apache.archiva.repository.content.ContentItem; -import org.apache.archiva.repository.content.ItemSelector; -import org.apache.archiva.repository.content.LayoutException; -import org.apache.archiva.repository.content.base.ArchivaItemSelector; -import org.apache.archiva.repository.maven.MavenSystemManager; -import org.apache.archiva.repository.metadata.RepositoryMetadataException; -import org.apache.archiva.repository.storage.StorageAsset; -import org.apache.commons.lang3.ArrayUtils; -import org.apache.commons.lang3.StringUtils; -import org.apache.maven.model.CiManagement; -import org.apache.maven.model.Dependency; -import org.apache.maven.model.DistributionManagement; -import org.apache.maven.model.IssueManagement; -import org.apache.maven.model.License; -import org.apache.maven.model.MailingList; -import org.apache.maven.model.Model; -import org.apache.maven.model.Organization; -import org.apache.maven.model.Relocation; -import org.apache.maven.model.Scm; -import org.apache.maven.model.building.DefaultModelBuilderFactory; -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.model.io.xpp3.MavenXpp3Reader; -import org.codehaus.plexus.util.xml.pull.XmlPullParserException; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.context.ApplicationContext; -import org.springframework.stereotype.Service; - -import javax.annotation.PostConstruct; -import javax.inject.Inject; -import javax.inject.Named; -import java.io.FileNotFoundException; -import java.io.IOException; -import java.io.Reader; -import java.nio.channels.Channels; -import java.nio.charset.Charset; -import java.nio.file.NoSuchFileException; -import java.time.ZoneId; -import java.time.ZonedDateTime; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collection; -import java.util.Collections; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.Set; -import java.util.function.Predicate; -import java.util.stream.Collectors; - -// import java.io.FileNotFoundException; - -/** - *

- * Maven 2 repository format storage implementation. This class currently takes parameters to indicate the repository to - * deal with rather than being instantiated per-repository. - * FIXME: instantiate one per repository and allocate permanently from a factory (which can be obtained within the session). - *

- *

- * The session is passed in as an argument to obtain any necessary resources, rather than the class being instantiated - * within the session in the context of a single managed repository's resolution needs. - *

- */ -@Service("repositoryStorage#maven2") -public class Maven2RepositoryStorage - implements RepositoryStorage { - - private static final Logger log = LoggerFactory.getLogger(Maven2RepositoryStorage.class); - - private ModelBuilder builder; - - @Inject - RepositoryRegistry repositoryRegistry; - - @Inject - @Named( "metadataReader#maven" ) - MavenMetadataReader metadataReader; - - @Inject - @Named("repositoryPathTranslator#maven2") - private RepositoryPathTranslator pathTranslator; - - @Inject - private WagonFactory wagonFactory; - - @Inject - private ApplicationContext applicationContext; - - @Inject - private ProxyRegistry proxyRegistry; - - @Inject - private MavenSystemManager mavenSystemManager; - - private static final String METADATA_FILENAME_START = "maven-metadata"; - - private static final String METADATA_FILENAME = METADATA_FILENAME_START + ".xml"; - - // This array must be lexically sorted - private static final String[] IGNORED_FILES = {METADATA_FILENAME, "resolver-status.properties"}; - - private static final MavenXpp3Reader MAVEN_XPP_3_READER = new MavenXpp3Reader(); - - - @PostConstruct - public void initialize() { - builder = new DefaultModelBuilderFactory().newInstance(); - - } - - @Override - public ProjectMetadata readProjectMetadata(String repoId, String namespace, String projectId) { - // TODO: could natively implement the "shared model" concept from the browse action to avoid needing it there? - return null; - } - - @Override - public ProjectVersionMetadata readProjectVersionMetadata(ReadMetadataRequest readMetadataRequest) - throws RepositoryStorageMetadataNotFoundException, RepositoryStorageMetadataInvalidException, - RepositoryStorageRuntimeException { - - ManagedRepository managedRepository = repositoryRegistry.getManagedRepository(readMetadataRequest.getRepositoryId()); - boolean isReleases = managedRepository.getActiveReleaseSchemes().contains(ReleaseScheme.RELEASE); - boolean isSnapshots = managedRepository.getActiveReleaseSchemes().contains(ReleaseScheme.SNAPSHOT); - String artifactVersion = readMetadataRequest.getProjectVersion(); - // olamy: in case of browsing via the ui we can mix repos (parent of a SNAPSHOT can come from release repo) - if (!readMetadataRequest.isBrowsingRequest()) { - if (VersionUtil.isSnapshot(artifactVersion)) { - // skygo trying to improve speed by honoring managed configuration MRM-1658 - if (isReleases && !isSnapshots) { - throw new RepositoryStorageRuntimeException("lookforsnaponreleaseonly", - "managed repo is configured for release only"); - } - } else { - if (!isReleases && isSnapshots) { - throw new RepositoryStorageRuntimeException("lookforsreleaseonsneponly", - "managed repo is configured for snapshot only"); - } - } - } - StorageAsset basedir = managedRepository.getRoot(); - if (VersionUtil.isSnapshot(artifactVersion)) { - StorageAsset metadataFile = pathTranslator.toFile(basedir, readMetadataRequest.getNamespace(), - readMetadataRequest.getProjectId(), artifactVersion, - METADATA_FILENAME); - try { - ArchivaRepositoryMetadata metadata = metadataReader.read(metadataFile); - - // re-adjust to timestamp if present, otherwise retain the original -SNAPSHOT filename - SnapshotVersion snapshotVersion = metadata.getSnapshotVersion(); - if (snapshotVersion != null) { - artifactVersion = - artifactVersion.substring(0, artifactVersion.length() - 8); // remove SNAPSHOT from end - artifactVersion = - artifactVersion + snapshotVersion.getTimestamp() + "-" + snapshotVersion.getBuildNumber(); - } - } catch ( RepositoryMetadataException e) { - // unable to parse metadata - LOGGER it, and continue with the version as the original SNAPSHOT version - log.warn("Invalid metadata: {} - {}", metadataFile, e.getMessage()); - } - } - - // TODO: won't work well with some other layouts, might need to convert artifact parts to ID by path translator - String id = readMetadataRequest.getProjectId() + "-" + artifactVersion + ".pom"; - StorageAsset file = - pathTranslator.toFile(basedir, readMetadataRequest.getNamespace(), readMetadataRequest.getProjectId(), - readMetadataRequest.getProjectVersion(), id); - - if (!file.exists()) { - // metadata could not be resolved - throw new RepositoryStorageMetadataNotFoundException( - "The artifact's POM file '" + file.getPath() + "' was missing"); - } - - // TODO: this is a workaround until we can properly resolve using proxies as well - this doesn't cache - // anything locally! - List remoteRepositories = new ArrayList<>(); - Map networkProxies = new HashMap<>(); - - Map> proxyConnectorsMap = proxyRegistry.getProxyConnectorAsMap(); - List proxyConnectors = proxyConnectorsMap.get(readMetadataRequest.getRepositoryId()); - if (proxyConnectors != null) { - for (ProxyConnector proxyConnector : proxyConnectors) { - RemoteRepository remoteRepoConfig = - repositoryRegistry.getRemoteRepository(proxyConnector.getTargetRepository().getId()); - - if (remoteRepoConfig != null) { - remoteRepositories.add(remoteRepoConfig); - - NetworkProxy networkProxyConfig = - proxyRegistry.getNetworkProxy(proxyConnector.getProxyId()); - - if (networkProxyConfig != null) { - // key/value: remote repo ID/proxy info - networkProxies.put(proxyConnector.getTargetRepository().getId(), networkProxyConfig); - } - } - } - } - - // That's a browsing request so we can a mix of SNAPSHOT and release artifacts (especially with snapshots which - // can have released parent pom - if (readMetadataRequest.isBrowsingRequest()) { - remoteRepositories.addAll(repositoryRegistry.getRemoteRepositories()); - } - - ModelBuildingRequest req = - new DefaultModelBuildingRequest().setProcessPlugins(false).setPomFile(file.getFilePath().toFile()).setTwoPhaseBuilding( - false).setValidationLevel(ModelBuildingRequest.VALIDATION_LEVEL_MINIMAL); - - //MRM-1607. olamy this will resolve jdk profiles on the current running archiva jvm - req.setSystemProperties(System.getProperties()); - - // MRM-1411 - req.setModelResolver( - new RepositoryModelResolver(managedRepository, pathTranslator, wagonFactory, remoteRepositories, - networkProxies, managedRepository, mavenSystemManager, metadataReader)); - - Model model; - try { - model = builder.build(req).getEffectiveModel(); - } catch (ModelBuildingException e) { - String msg = "The artifact's POM file '" + file + "' was invalid: " + e.getMessage(); - - List 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! - // olamy really hackhish but fail with java profile so use error message - // || ( StringUtils.startsWith( problem.getMessage(), "Failed to determine Java version for profile" ) ) - // but setTwoPhaseBuilding(true) fix that - if (((problem.getException() instanceof FileNotFoundException - || problem.getException() instanceof NoSuchFileException - ) && e.getModelId() != null && - !e.getModelId().equals(problem.getModelId()))) { - log.warn("The artifact's parent POM file '{}' cannot be resolved. " - + "Using defaults for project version metadata..", file); - - ProjectVersionMetadata metadata = new ProjectVersionMetadata(); - metadata.setId(readMetadataRequest.getProjectVersion()); - - MavenProjectFacet facet = new MavenProjectFacet(); - facet.setGroupId(readMetadataRequest.getNamespace()); - facet.setArtifactId(readMetadataRequest.getProjectId()); - facet.setPackaging("jar"); - metadata.addFacet(facet); - - String errMsg = - "Error in resolving artifact's parent POM file. " + (problem.getException() == null - ? problem.getMessage() - : problem.getException().getMessage()); - RepositoryProblemFacet repoProblemFacet = new RepositoryProblemFacet(); - repoProblemFacet.setRepositoryId(readMetadataRequest.getRepositoryId()); - repoProblemFacet.setId(readMetadataRequest.getRepositoryId()); - repoProblemFacet.setMessage(errMsg); - repoProblemFacet.setProblem(errMsg); - repoProblemFacet.setProject(readMetadataRequest.getProjectId()); - repoProblemFacet.setVersion(readMetadataRequest.getProjectVersion()); - repoProblemFacet.setNamespace(readMetadataRequest.getNamespace()); - - metadata.addFacet(repoProblemFacet); - - return metadata; - } - } - - throw new RepositoryStorageMetadataInvalidException("invalid-pom", msg, e); - } - - // Check if the POM is in the correct location - boolean correctGroupId = readMetadataRequest.getNamespace().equals(model.getGroupId()); - boolean correctArtifactId = readMetadataRequest.getProjectId().equals(model.getArtifactId()); - boolean correctVersion = readMetadataRequest.getProjectVersion().equals(model.getVersion()); - if (!correctGroupId || !correctArtifactId || !correctVersion) { - StringBuilder message = new StringBuilder("Incorrect POM coordinates in '" + file + "':"); - if (!correctGroupId) { - message.append("\nIncorrect group ID: ").append(model.getGroupId()); - } - if (!correctArtifactId) { - message.append("\nIncorrect artifact ID: ").append(model.getArtifactId()); - } - if (!correctVersion) { - message.append("\nIncorrect version: ").append(model.getVersion()); - } - - throw new RepositoryStorageMetadataInvalidException("mislocated-pom", message.toString()); - } - - ProjectVersionMetadata metadata = new ProjectVersionMetadata(); - metadata.setCiManagement(convertCiManagement(model.getCiManagement())); - metadata.setDescription(model.getDescription()); - metadata.setId(readMetadataRequest.getProjectVersion()); - metadata.setIssueManagement(convertIssueManagement(model.getIssueManagement())); - metadata.setLicenses(convertLicenses(model.getLicenses())); - metadata.setMailingLists(convertMailingLists(model.getMailingLists())); - metadata.setDependencies(convertDependencies(model.getDependencies())); - metadata.setName(model.getName()); - metadata.setOrganization(convertOrganization(model.getOrganization())); - metadata.setScm(convertScm(model.getScm())); - metadata.setUrl(model.getUrl()); - metadata.setProperties( new HashMap( (Map) model.getProperties( ) ) ); - - MavenProjectFacet facet = new MavenProjectFacet(); - facet.setGroupId(model.getGroupId() != null ? model.getGroupId() : model.getParent().getGroupId()); - facet.setArtifactId(model.getArtifactId()); - facet.setPackaging(model.getPackaging()); - if (model.getParent() != null) { - MavenProjectParent parent = new MavenProjectParent(); - parent.setGroupId(model.getParent().getGroupId()); - parent.setArtifactId(model.getParent().getArtifactId()); - parent.setVersion(model.getParent().getVersion()); - facet.setParent(parent); - } - metadata.addFacet(facet); - - return metadata; - - - } - - public void setWagonFactory(WagonFactory wagonFactory) { - this.wagonFactory = wagonFactory; - } - - private List convertDependencies(List dependencies) { - List l = new ArrayList<>(); - for (Dependency dependency : dependencies) { - org.apache.archiva.metadata.model.Dependency newDependency = - new org.apache.archiva.metadata.model.Dependency(); - newDependency.setArtifactId(dependency.getArtifactId()); - newDependency.setClassifier(dependency.getClassifier()); - newDependency.setNamespace(dependency.getGroupId()); - newDependency.setOptional(dependency.isOptional()); - newDependency.setScope(dependency.getScope()); - newDependency.setSystemPath(dependency.getSystemPath()); - newDependency.setType(dependency.getType()); - newDependency.setVersion(dependency.getVersion()); - l.add(newDependency); - } - return l; - } - - private org.apache.archiva.metadata.model.Scm convertScm(Scm scm) { - org.apache.archiva.metadata.model.Scm newScm = null; - if (scm != null) { - newScm = new org.apache.archiva.metadata.model.Scm(); - newScm.setConnection(scm.getConnection()); - newScm.setDeveloperConnection(scm.getDeveloperConnection()); - newScm.setUrl(scm.getUrl()); - } - return newScm; - } - - private org.apache.archiva.metadata.model.Organization convertOrganization(Organization organization) { - org.apache.archiva.metadata.model.Organization org = null; - if (organization != null) { - org = new org.apache.archiva.metadata.model.Organization(); - org.setName(organization.getName()); - org.setUrl(organization.getUrl()); - } - return org; - } - - private List convertLicenses(List licenses) { - List l = new ArrayList<>(); - for (License license : licenses) { - org.apache.archiva.metadata.model.License newLicense = new org.apache.archiva.metadata.model.License(); - newLicense.setName(license.getName()); - newLicense.setUrl(license.getUrl()); - l.add(newLicense); - } - return l; - } - - private List convertMailingLists(List mailingLists) { - List l = new ArrayList<>(); - for (MailingList mailingList : mailingLists) { - org.apache.archiva.metadata.model.MailingList newMailingList = - new org.apache.archiva.metadata.model.MailingList(); - newMailingList.setName(mailingList.getName()); - newMailingList.setMainArchiveUrl(mailingList.getArchive()); - newMailingList.setPostAddress(mailingList.getPost()); - newMailingList.setSubscribeAddress(mailingList.getSubscribe()); - newMailingList.setUnsubscribeAddress(mailingList.getUnsubscribe()); - newMailingList.setOtherArchives(mailingList.getOtherArchives()); - l.add(newMailingList); - } - return l; - } - - private org.apache.archiva.metadata.model.IssueManagement convertIssueManagement(IssueManagement issueManagement) { - org.apache.archiva.metadata.model.IssueManagement im = null; - if (issueManagement != null) { - im = new org.apache.archiva.metadata.model.IssueManagement(); - im.setSystem(issueManagement.getSystem()); - im.setUrl(issueManagement.getUrl()); - } - return im; - } - - private org.apache.archiva.metadata.model.CiManagement convertCiManagement(CiManagement ciManagement) { - org.apache.archiva.metadata.model.CiManagement ci = null; - if (ciManagement != null) { - ci = new org.apache.archiva.metadata.model.CiManagement(); - ci.setSystem(ciManagement.getSystem()); - ci.setUrl(ciManagement.getUrl()); - } - return ci; - } - - @Override - public Collection listRootNamespaces(String repoId, Filter filter) - throws RepositoryStorageRuntimeException { - StorageAsset dir = getRepositoryBasedir(repoId); - - return getSortedFiles(dir, filter); - } - - private static Collection getSortedFiles(StorageAsset dir, Filter filter) { - - final Predicate dFilter = new DirectoryFilter(filter); - return dir.list().stream().filter(f -> f.isContainer()) - .filter(dFilter) - .map(path -> path.getName().toString()) - .sorted().collect(Collectors.toList()); - - } - - private StorageAsset getRepositoryBasedir(String repoId) - throws RepositoryStorageRuntimeException { - ManagedRepository repository = repositoryRegistry.getManagedRepository(repoId); - - return repository.getRoot(); - } - - @Override - public Collection listNamespaces(String repoId, String namespace, Filter filter) - throws RepositoryStorageRuntimeException { - StorageAsset dir = pathTranslator.toFile(getRepositoryBasedir(repoId), namespace); - if (!(dir.exists()) && !dir.isContainer()) { - return Collections.emptyList(); - } - // scan all the directories which are potential namespaces. Any directories known to be projects are excluded - Predicate dFilter = new DirectoryFilter(filter); - return dir.list().stream().filter(dFilter).filter(path -> !isProject(path, filter)).map(path -> path.getName().toString()) - .sorted().collect(Collectors.toList()); - } - - @Override - public Collection listProjects(String repoId, String namespace, Filter filter) - throws RepositoryStorageRuntimeException { - StorageAsset dir = pathTranslator.toFile(getRepositoryBasedir(repoId), namespace); - if (!(dir.exists() && dir.isContainer())) { - return Collections.emptyList(); - } - // scan all directories in the namespace, and only include those that are known to be projects - final Predicate dFilter = new DirectoryFilter(filter); - return dir.list().stream().filter(dFilter).filter(path -> isProject(path, filter)).map(path -> path.getName().toString()) - .sorted().collect(Collectors.toList()); - - } - - @Override - public Collection listProjectVersions(String repoId, String namespace, String projectId, - Filter filter) - throws RepositoryStorageRuntimeException { - StorageAsset dir = pathTranslator.toFile(getRepositoryBasedir(repoId), namespace, projectId); - if (!(dir.exists() && dir.isContainer())) { - return Collections.emptyList(); - } - - // all directories in a project directory can be considered a version - return getSortedFiles(dir, filter); - } - - @Override - public Collection readArtifactsMetadata(ReadMetadataRequest readMetadataRequest) - throws RepositoryStorageRuntimeException { - StorageAsset dir = pathTranslator.toFile(getRepositoryBasedir(readMetadataRequest.getRepositoryId()), - readMetadataRequest.getNamespace(), readMetadataRequest.getProjectId(), - readMetadataRequest.getProjectVersion()); - if (!(dir.exists() && dir.isContainer())) { - return Collections.emptyList(); - } - - // all files that are not metadata and not a checksum / signature are considered artifacts - final Predicate dFilter = new ArtifactDirectoryFilter(readMetadataRequest.getFilter()); - // Returns a map TRUE -> (success values), FALSE -> (Exceptions) - Map>> result = dir.list().stream().filter(dFilter).map(path -> { - try { - return Try.success(getArtifactFromFile(readMetadataRequest.getRepositoryId(), readMetadataRequest.getNamespace(), - readMetadataRequest.getProjectId(), readMetadataRequest.getProjectVersion(), - path)); - } catch (Exception e) { - log.debug("Could not create metadata for {}: {}", path, e.getMessage(), e); - return Try.failure(e); - } - } - ).collect(Collectors.groupingBy(Try::isSuccess)); - if (result.containsKey(Boolean.FALSE) && result.get(Boolean.FALSE).size() > 0 && (!result.containsKey(Boolean.TRUE) || result.get(Boolean.TRUE).size() == 0)) { - log.error("Could not get artifact metadata. Directory: {}. Number of errors {}.", dir, result.get(Boolean.FALSE).size()); - Try failure = result.get(Boolean.FALSE).get(0); - log.error("Sample exception {}", failure.getError().getMessage(), failure.getError()); - throw new RepositoryStorageRuntimeException(readMetadataRequest.getRepositoryId(), "Could not retrieve metadata of the files"); - } else { - if (!result.containsKey(Boolean.TRUE) || result.get(Boolean.TRUE) == null) { - return Collections.emptyList(); - } - return result.get(Boolean.TRUE).stream().map(tr -> tr.get()).collect(Collectors.toList()); - } - - } - - @Override - public ArtifactMetadata readArtifactMetadataFromPath(String repoId, String path) - throws RepositoryStorageRuntimeException { - ArtifactMetadata metadata = pathTranslator.getArtifactForPath(repoId, path); - - try { - populateArtifactMetadataFromFile(metadata, getRepositoryBasedir(repoId).resolve(path)); - } catch (IOException e) { - throw new RepositoryStorageRuntimeException(repoId, "Error during metadata retrieval of " + path + " :" + e.getMessage(), e); - } - - return metadata; - } - - private ArtifactMetadata getArtifactFromFile(String repoId, String namespace, String projectId, - String projectVersion, StorageAsset file) throws IOException { - ArtifactMetadata metadata = - pathTranslator.getArtifactFromId(repoId, namespace, projectId, projectVersion, file.getName()); - - populateArtifactMetadataFromFile(metadata, file); - - return metadata; - } - - @Override - public ItemSelector applyServerSideRelocation(ManagedRepository managedRepository, ItemSelector artifactSelector) - throws ProxyDownloadException { - if ("pom".equals(artifactSelector.getType())) { - return artifactSelector; - } - - // Build the artifact POM reference - BaseRepositoryContentLayout layout; - try - { - layout = managedRepository.getContent( ).getLayout( BaseRepositoryContentLayout.class ); - } - catch ( LayoutException e ) - { - throw new ProxyDownloadException( "Could not set layout " + e.getMessage( ), new HashMap<>( ) ); - } - - RepositoryType repositoryType = managedRepository.getType(); - if (!proxyRegistry.hasHandler(repositoryType)) { - throw new ProxyDownloadException("No proxy handler found for repository type " + repositoryType, new HashMap<>()); - } - - - - ItemSelector selector = ArchivaItemSelector.builder( ) - .withNamespace( artifactSelector.getNamespace( ) ) - .withProjectId( artifactSelector.getArtifactId( ) ) - .withArtifactId( artifactSelector.getArtifactId( ) ) - .withVersion( artifactSelector.getVersion( ) ) - .withArtifactVersion( artifactSelector.getVersion( ) ) - .withType( "pom" ).build( ); - - Artifact pom = layout.getArtifact( selector ); - - RepositoryProxyHandler proxyHandler = proxyRegistry.getHandler(repositoryType).get(0); - - // Get the artifact POM from proxied repositories if needed - proxyHandler.fetchFromProxies(managedRepository, pom); - - // Open and read the POM from the managed repo - - if (!pom.exists()) { - return artifactSelector; - } - - try { - // MavenXpp3Reader leaves the file open, so we need to close it ourselves. - - Model model; - try (Reader reader = Channels.newReader(pom.getAsset().getReadChannel(), Charset.defaultCharset().name())) { - model = MAVEN_XPP_3_READER.read(reader); - } - - DistributionManagement dist = model.getDistributionManagement(); - if (dist != null) { - Relocation relocation = dist.getRelocation(); - if (relocation != null) { - ArchivaItemSelector.Builder relocatedBuilder = ArchivaItemSelector.builder( ); - // artifact is relocated : update the repositoryPath - if (relocation.getGroupId() != null) { - relocatedBuilder.withNamespace( relocation.getGroupId( ) ); - } else { - relocatedBuilder.withNamespace( artifactSelector.getNamespace( ) ); - } - if (relocation.getArtifactId() != null) { - relocatedBuilder.withArtifactId( relocation.getArtifactId( ) ); - } else { - relocatedBuilder.withArtifactId( artifactSelector.getArtifactId( ) ); - } - if (relocation.getVersion() != null) - { - relocatedBuilder.withVersion( relocation.getVersion( ) ); - } else { - relocatedBuilder.withVersion( artifactSelector.getVersion( ) ); - } - return relocatedBuilder.withArtifactVersion( artifactSelector.getArtifactVersion( ) ) - .withClassifier( artifactSelector.getClassifier( ) ) - .withType( artifactSelector.getType( ) ) - .withProjectId( artifactSelector.getProjectId( ) ) - .withExtension( artifactSelector.getExtension( ) ) - .build( ); - } - } - } catch (IOException e) { - // Unable to read POM : ignore. - } catch (XmlPullParserException e) { - // Invalid POM : ignore - } - return artifactSelector; - } - - - @Override - public String getFilePath(String requestPath, org.apache.archiva.repository.ManagedRepository managedRepository) { - // managedRepository can be null - // extract artifact reference from url - // groupId:artifactId:version:packaging:classifier - //org/apache/archiva/archiva-checksum/1.4-M4-SNAPSHOT/archiva-checksum-1.4-M4-SNAPSHOT.jar - String logicalResource = null; - String requestPathInfo = StringUtils.defaultString(requestPath); - - //remove prefix ie /repository/blah becomes /blah - requestPathInfo = removePrefix(requestPathInfo); - - // Remove prefixing slash as the repository id doesn't contain it; - if (requestPathInfo.startsWith("/")) { - requestPathInfo = requestPathInfo.substring(1); - } - - int slash = requestPathInfo.indexOf('/'); - if (slash > 0) { - logicalResource = requestPathInfo.substring(slash); - - if (logicalResource.endsWith("/..")) { - logicalResource += "/"; - } - - if (logicalResource != null && logicalResource.startsWith("//")) { - logicalResource = logicalResource.substring(1); - } - - if (logicalResource == null) { - logicalResource = "/"; - } - } else { - logicalResource = "/"; - } - return logicalResource; - - } - - @Override - public String getFilePathWithVersion(final String requestPath, ManagedRepositoryContent managedRepositoryContent) - throws RelocationException - { - - if (StringUtils.endsWith(requestPath, METADATA_FILENAME)) { - return getFilePath(requestPath, managedRepositoryContent.getRepository()); - } - - String filePath = getFilePath(requestPath, managedRepositoryContent.getRepository()); - Artifact artifact; - try - { - ContentItem item = managedRepositoryContent.toItem( filePath ); - artifact = managedRepositoryContent.getLayout( BaseRepositoryContentLayout.class ).adaptItem( Artifact.class, item ); - } - catch ( LayoutException e ) - { - return filePath; - } - - if (VersionUtil.isGenericSnapshot(artifact.getArtifactVersion())) { - // read maven metadata to get last timestamp - StorageAsset metadataDir = managedRepositoryContent.getRepository().getAsset(filePath).getParent(); - if (!metadataDir.exists()) { - return filePath; - } - StorageAsset metadataFile = metadataDir.resolve(METADATA_FILENAME); - if (!metadataFile.exists()) { - return filePath; - } - ArchivaRepositoryMetadata archivaRepositoryMetadata = null; - try - { - archivaRepositoryMetadata = metadataReader.read(metadataFile); - } - catch ( RepositoryMetadataException e ) - { - log.error( "Could not read metadata {}", e.getMessage( ), e ); - return filePath; - } - int buildNumber = archivaRepositoryMetadata.getSnapshotVersion().getBuildNumber(); - String timestamp = archivaRepositoryMetadata.getSnapshotVersion().getTimestamp(); - - // MRM-1846 - if (buildNumber < 1 && timestamp == null) { - return filePath; - } - - // org/apache/archiva/archiva-checksum/1.4-M4-SNAPSHOT/archiva-checksum-1.4-M4-SNAPSHOT.jar - // -> archiva-checksum-1.4-M4-20130425.081822-1.jar - - filePath = StringUtils.replace(filePath, // - artifact.getId() // - + "-" + artifact.getVersion().getId(), // - artifact.getId() // - + "-" + StringUtils.remove(artifact.getArtifactVersion(), - "-" + VersionUtil.SNAPSHOT) // - + "-" + timestamp // - + "-" + buildNumber); - - throw new RelocationException("/repository/" + managedRepositoryContent.getRepository().getId() + - (StringUtils.startsWith(filePath, "/") ? "" : "/") + filePath, - RelocationException.RelocationType.TEMPORARY); - - } - - return filePath; - } - - //----------------------------- - // internal - //----------------------------- - - /** - * FIXME remove - * - * @param href - * @return - */ - private static String removePrefix(final String href) { - String[] parts = StringUtils.split(href, '/'); - parts = (String[]) ArrayUtils.subarray(parts, 1, parts.length); - if (parts == null || parts.length == 0) { - return "/"; - } - - String joinedString = StringUtils.join(parts, '/'); - if (href.endsWith("/")) { - joinedString = joinedString + "/"; - } - - return joinedString; - } - - private static void populateArtifactMetadataFromFile(ArtifactMetadata metadata, StorageAsset file) throws IOException { - metadata.setWhenGathered(ZonedDateTime.now(ZoneId.of("GMT"))); - metadata.setFileLastModified(file.getModificationTime().toEpochMilli()); - ChecksummedFile checksummedFile = new ChecksummedFile(file.getFilePath()); - try { - metadata.setMd5(checksummedFile.calculateChecksum(ChecksumAlgorithm.MD5)); - } catch (IOException e) { - log.error("Unable to checksum file {}: {},MD5", file, e.getMessage()); - } - try { - metadata.setSha1(checksummedFile.calculateChecksum(ChecksumAlgorithm.SHA1)); - } catch (IOException e) { - log.error("Unable to checksum file {}: {},SHA1", file, e.getMessage()); - } - metadata.setSize(file.getSize()); - } - - private boolean isProject(StorageAsset dir, Filter filter) { - // scan directories for a valid project version subdirectory, meaning this must be a project directory - final Predicate dFilter = new DirectoryFilter(filter); - boolean projFound = dir.list().stream().filter(dFilter) - .anyMatch(path -> isProjectVersion(path)); - if (projFound) { - return true; - } - - // if a metadata file is present, check if this is the "artifactId" directory, marking it as a project - ArchivaRepositoryMetadata metadata = readMetadata(dir); - if (metadata != null && dir.getName().toString().equals(metadata.getArtifactId())) { - return true; - } - - return false; - } - - private boolean isProjectVersion(StorageAsset dir) { - final String artifactId = dir.getParent().getName(); - final String projectVersion = dir.getName(); - - // check if there is a POM artifact file to ensure it is a version directory - - Predicate filter; - if (VersionUtil.isSnapshot(projectVersion)) { - filter = new PomFilenameFilter(artifactId, projectVersion); - } else { - final String pomFile = artifactId + "-" + projectVersion + ".pom"; - filter = new PomFileFilter(pomFile); - } - if (dir.list().stream().filter(f -> !f.isContainer()).anyMatch(filter)) { - return true; - } - // if a metadata file is present, check if this is the "version" directory, marking it as a project version - ArchivaRepositoryMetadata metadata = readMetadata(dir); - if (metadata != null && projectVersion.equals(metadata.getVersion())) { - return true; - } - - return false; - } - - private ArchivaRepositoryMetadata readMetadata(StorageAsset directory) { - ArchivaRepositoryMetadata metadata = null; - StorageAsset metadataFile = directory.resolve(METADATA_FILENAME); - if (metadataFile.exists()) { - try { - metadata = metadataReader.read(metadataFile); - } catch ( RepositoryMetadataException e ) - { - // Ignore missing or invalid metadata - } - } - return metadata; - } - - private static class DirectoryFilter - implements Predicate { - private final Filter filter; - - public DirectoryFilter(Filter filter) { - this.filter = filter; - } - - @Override - public boolean test(StorageAsset dir) { - final String name = dir.getName(); - if (!filter.accept(name)) { - return false; - } else if (name.startsWith(".")) { - return false; - } else if (!dir.isContainer()) { - return false; - } - return true; - } - } - - private static class ArtifactDirectoryFilter - implements Predicate { - private final Filter filter; - - private ArtifactDirectoryFilter(Filter filter) { - this.filter = filter; - } - - @Override - public boolean test(StorageAsset file) { - final Set checksumExts = ChecksumAlgorithm.getAllExtensions(); - final String path = file.getPath(); - final String name = file.getName(); - final String extension = StringUtils.substringAfterLast(name, ".").toLowerCase(); - // TODO compare to logic in maven-repository-layer - if (file.isContainer()) { - return false; - } else if (!filter.accept(name)) { - return false; - } else if (name.startsWith(".") || path.contains("/.") ) { - return false; - } else if (checksumExts.contains(extension)) { - return false; - } else if (Arrays.binarySearch(IGNORED_FILES, name) >= 0) { - return false; - } - // some files from remote repositories can have name like maven-metadata-archiva-vm-all-public.xml - else if (StringUtils.startsWith(name, METADATA_FILENAME_START) && StringUtils.endsWith(name, ".xml")) { - return false; - } - - return true; - - } - } - - - private static final class PomFilenameFilter - implements Predicate { - - private final String artifactId, projectVersion; - - private PomFilenameFilter(String artifactId, String projectVersion) { - this.artifactId = artifactId; - this.projectVersion = projectVersion; - } - - @Override - public boolean test(StorageAsset dir) { - final String name = dir.getName(); - if (name.startsWith(artifactId + "-") && name.endsWith(".pom")) { - String v = name.substring(artifactId.length() + 1, name.length() - 4); - v = VersionUtil.getBaseVersion(v); - if (v.equals(projectVersion)) { - return true; - } - } - return false; - } - - } - - private static class PomFileFilter - implements Predicate { - private final String pomFile; - - private PomFileFilter(String pomFile) { - this.pomFile = pomFile; - } - - @Override - public boolean test(StorageAsset dir) { - return pomFile.equals(dir.getName()); - } - } - -} diff --git a/archiva-modules/archiva-maven/archiva-maven-repository/src/main/java/org/apache/archiva/repository/maven/metadata/storage/MavenArtifactFacetFactory.java b/archiva-modules/archiva-maven/archiva-maven-repository/src/main/java/org/apache/archiva/repository/maven/metadata/storage/MavenArtifactFacetFactory.java deleted file mode 100644 index a1ad2e5ae..000000000 --- a/archiva-modules/archiva-maven/archiva-maven-repository/src/main/java/org/apache/archiva/repository/maven/metadata/storage/MavenArtifactFacetFactory.java +++ /dev/null @@ -1,47 +0,0 @@ -package org.apache.archiva.repository.maven.metadata.storage; - -/* - * 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.maven.metadata.model.MavenArtifactFacet; -import org.apache.archiva.metadata.model.facets.AbstractMetadataFacetFactory; -import org.springframework.stereotype.Service; - -/** - * - */ -@Service("metadataFacetFactory#org.apache.archiva.metadata.repository.storage.maven2.artifact") -public class MavenArtifactFacetFactory - extends AbstractMetadataFacetFactory -{ - public MavenArtifactFacetFactory() { - super( MavenArtifactFacet.class); - } - - @Override - public MavenArtifactFacet createMetadataFacet() - { - return new MavenArtifactFacet(); - } - - @Override - public MavenArtifactFacet createMetadataFacet( String repositoryId, String name ) - { - throw new UnsupportedOperationException( "There is no valid name for artifact facets" ); - } -} \ No newline at end of file diff --git a/archiva-modules/archiva-maven/archiva-maven-repository/src/main/java/org/apache/archiva/repository/maven/metadata/storage/MavenProjectFacet.java b/archiva-modules/archiva-maven/archiva-maven-repository/src/main/java/org/apache/archiva/repository/maven/metadata/storage/MavenProjectFacet.java deleted file mode 100644 index 07f971027..000000000 --- a/archiva-modules/archiva-maven/archiva-maven-repository/src/main/java/org/apache/archiva/repository/maven/metadata/storage/MavenProjectFacet.java +++ /dev/null @@ -1,163 +0,0 @@ -package org.apache.archiva.repository.maven.metadata.storage; - -/* - * 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.metadata.model.MetadataFacet; - -import java.util.HashMap; -import java.util.Map; - -public class MavenProjectFacet - implements MetadataFacet -{ - private String groupId; - - private String artifactId; - - private MavenProjectParent parent; - - private String packaging; - - public static final String FACET_ID = "org.apache.archiva.metadata.repository.storage.maven2.project"; - - public String getGroupId() - { - return groupId; - } - - public void setGroupId( String groupId ) - { - this.groupId = groupId; - } - - public String getArtifactId() - { - return artifactId; - } - - public void setArtifactId( String artifactId ) - { - this.artifactId = artifactId; - } - - public MavenProjectParent getParent() - { - return parent; - } - - public void setParent( MavenProjectParent parent ) - { - this.parent = parent; - } - - public String getPackaging() - { - return packaging; - } - - public void setPackaging( String packaging ) - { - this.packaging = packaging; - } - - @Override - public String getFacetId() - { - return FACET_ID; - } - - @Override - public String getName() - { - // TODO: not needed, perhaps version metadata facet should be separate interface? - return null; - } - - @Override - public Map toProperties() - { - HashMap properties = new HashMap<>(); - properties.put( "groupId", groupId ); - properties.put( "artifactId", artifactId ); - properties.put( "packaging", packaging ); - if ( parent != null ) - { - properties.put( "parent.groupId", parent.getGroupId() ); - properties.put( "parent.artifactId", parent.getArtifactId() ); - properties.put( "parent.version", parent.getVersion() ); - } - return properties; - } - - @Override - public void fromProperties( Map properties ) - { - groupId = properties.get( "groupId" ); - artifactId = properties.get( "artifactId" ); - packaging = properties.get( "packaging" ); - String parentArtifactId = properties.get( "parent.artifactId" ); - if ( parentArtifactId != null ) - { - MavenProjectParent parent = new MavenProjectParent(); - parent.setGroupId( properties.get( "parent.groupId" ) ); - parent.setArtifactId( parentArtifactId ); - parent.setVersion( properties.get( "parent.version" ) ); - this.parent = parent; - } - } - - @Override - public boolean equals( Object o ) - { - if ( this == o ) - { - return true; - } - if ( !( o instanceof MavenProjectFacet ) ) - { - return false; - } - - MavenProjectFacet that = (MavenProjectFacet) o; - - if ( !artifactId.equals( that.artifactId ) ) - { - return false; - } - if ( !groupId.equals( that.groupId ) ) - { - return false; - } - if ( !packaging.equals( that.packaging ) ) - { - return false; - } - - return true; - } - - @Override - public int hashCode() - { - int result = groupId.hashCode(); - result = 31 * result + artifactId.hashCode(); - result = 31 * result + packaging.hashCode(); - return result; - } -} diff --git a/archiva-modules/archiva-maven/archiva-maven-repository/src/main/java/org/apache/archiva/repository/maven/metadata/storage/MavenProjectFacetFactory.java b/archiva-modules/archiva-maven/archiva-maven-repository/src/main/java/org/apache/archiva/repository/maven/metadata/storage/MavenProjectFacetFactory.java deleted file mode 100644 index bde26a01d..000000000 --- a/archiva-modules/archiva-maven/archiva-maven-repository/src/main/java/org/apache/archiva/repository/maven/metadata/storage/MavenProjectFacetFactory.java +++ /dev/null @@ -1,46 +0,0 @@ -package org.apache.archiva.repository.maven.metadata.storage; - -/* - * 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.metadata.model.facets.AbstractMetadataFacetFactory; -import org.springframework.stereotype.Service; - -/** - * - */ -@Service( "metadataFacetFactory#org.apache.archiva.metadata.repository.storage.maven2.project" ) -public class MavenProjectFacetFactory - extends AbstractMetadataFacetFactory -{ - public MavenProjectFacetFactory() { - super( MavenProjectFacet.class ); - } - - @Override - public MavenProjectFacet createMetadataFacet() - { - return new MavenProjectFacet(); - } - - @Override - public MavenProjectFacet createMetadataFacet( String repositoryId, String name ) - { - throw new UnsupportedOperationException( "There is no valid name for project version facets" ); - } -} diff --git a/archiva-modules/archiva-maven/archiva-maven-repository/src/main/java/org/apache/archiva/repository/maven/metadata/storage/MavenProjectParent.java b/archiva-modules/archiva-maven/archiva-maven-repository/src/main/java/org/apache/archiva/repository/maven/metadata/storage/MavenProjectParent.java deleted file mode 100644 index e6ad491b5..000000000 --- a/archiva-modules/archiva-maven/archiva-maven-repository/src/main/java/org/apache/archiva/repository/maven/metadata/storage/MavenProjectParent.java +++ /dev/null @@ -1,58 +0,0 @@ -package org.apache.archiva.repository.maven.metadata.storage; - -/* - * 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. - */ - -public class MavenProjectParent -{ - private String groupId; - - private String artifactId; - - private String version; - - public String getVersion() - { - return version; - } - - public void setVersion( String version ) - { - this.version = version; - } - - public String getArtifactId() - { - return artifactId; - } - - public void setArtifactId( String artifactId ) - { - this.artifactId = artifactId; - } - - public String getGroupId() - { - return groupId; - } - - public void setGroupId( String groupId ) - { - this.groupId = groupId; - } -} diff --git a/archiva-modules/archiva-maven/archiva-maven-repository/src/main/java/org/apache/archiva/repository/maven/metadata/storage/RepositoryModelResolver.java b/archiva-modules/archiva-maven/archiva-maven-repository/src/main/java/org/apache/archiva/repository/maven/metadata/storage/RepositoryModelResolver.java deleted file mode 100644 index 187f5760e..000000000 --- a/archiva-modules/archiva-maven/archiva-maven-repository/src/main/java/org/apache/archiva/repository/maven/metadata/storage/RepositoryModelResolver.java +++ /dev/null @@ -1,597 +0,0 @@ -package org.apache.archiva.repository.maven.metadata.storage; - -/* - * 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.utils.VersionUtil; -import org.apache.archiva.maven.metadata.MavenMetadataReader; -import org.apache.archiva.metadata.repository.storage.RepositoryPathTranslator; -import org.apache.archiva.model.ArchivaRepositoryMetadata; -import org.apache.archiva.model.SnapshotVersion; -import org.apache.archiva.maven.common.proxy.WagonFactory; -import org.apache.archiva.maven.common.proxy.WagonFactoryException; -import org.apache.archiva.maven.common.proxy.WagonFactoryRequest; -import org.apache.archiva.proxy.model.NetworkProxy; -import org.apache.archiva.repository.ManagedRepository; -import org.apache.archiva.repository.RemoteRepository; -import org.apache.archiva.repository.RepositoryCredentials; -import org.apache.archiva.repository.maven.MavenSystemManager; -import org.apache.archiva.repository.metadata.RepositoryMetadataException; -import org.apache.archiva.repository.storage.StorageAsset; -import org.apache.commons.lang3.StringUtils; -import org.apache.http.auth.UsernamePasswordCredentials; -import org.apache.maven.model.Dependency; -import org.apache.maven.model.Parent; -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.eclipse.aether.RepositorySystemSession; -import org.eclipse.aether.artifact.Artifact; -import org.eclipse.aether.artifact.DefaultArtifact; -import org.eclipse.aether.impl.VersionRangeResolver; -import org.eclipse.aether.resolution.VersionRangeRequest; -import org.eclipse.aether.resolution.VersionRangeResolutionException; -import org.eclipse.aether.resolution.VersionRangeResult; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import java.io.IOException; -import java.nio.file.Files; -import java.nio.file.Path; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -public class RepositoryModelResolver - implements ModelResolver -{ - - private final Map networkProxyMap = new HashMap<>(); - - private RepositorySystemSession session; - private VersionRangeResolver versionRangeResolver; - - private StorageAsset basedir; - - private RepositoryPathTranslator pathTranslator; - - private WagonFactory wagonFactory; - - private List remoteRepositories; - - private ManagedRepository targetRepository; - - private static final Logger log = LoggerFactory.getLogger( RepositoryModelResolver.class ); - - private static final String METADATA_FILENAME = "maven-metadata.xml"; - - private MavenSystemManager mavenSystemManager; - - private MavenMetadataReader metadataReader; - - - - private ManagedRepository managedRepository; - - public RepositoryModelResolver(StorageAsset basedir, RepositoryPathTranslator pathTranslator) - { - this.basedir = basedir; - - this.pathTranslator = pathTranslator; - - } - - public RepositoryModelResolver(ManagedRepository managedRepository, RepositoryPathTranslator pathTranslator, - WagonFactory wagonFactory, List remoteRepositories, - Map networkProxiesMap, ManagedRepository targetRepository, - MavenSystemManager mavenSystemManager, MavenMetadataReader metadataReader) - { - this( managedRepository.getRoot(), pathTranslator ); - - this.managedRepository = managedRepository; - - this.wagonFactory = wagonFactory; - - this.remoteRepositories = remoteRepositories; - - this.networkProxyMap.clear(); - this.networkProxyMap.putAll(networkProxiesMap); - - this.targetRepository = targetRepository; - - this.session = MavenSystemManager.newRepositorySystemSession( managedRepository.getRoot().getFilePath().toString() ); - - this.versionRangeResolver = mavenSystemManager.getLocator().getService(VersionRangeResolver.class); - - this.mavenSystemManager = mavenSystemManager; - this.metadataReader = metadataReader; - } - - - @Override - 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 - - StorageAsset model = pathTranslator.toFile( basedir, groupId, artifactId, version, filename ); - - if ( !model.exists() ) - { - /** - * - */ - // is a SNAPSHOT ? so we can try to find locally before asking remote repositories. - if ( StringUtils.contains( version, VersionUtil.SNAPSHOT ) ) - { - Path localSnapshotModel = findTimeStampedSnapshotPom( groupId, artifactId, version, model.getParent().getFilePath() ); - if ( localSnapshotModel != null ) - { - return new FileModelSource( localSnapshotModel.toFile() ); - } - - } - - for ( RemoteRepository remoteRepository : remoteRepositories ) - { - try - { - boolean success = getModelFromProxy( remoteRepository, groupId, artifactId, version, filename ); - if ( success && model.exists() ) - { - log.info( "Model '{}' successfully retrieved from remote repository '{}'", - model.getPath(), remoteRepository.getId() ); - break; - } - } - catch ( ResourceDoesNotExistException e ) - { - log.info( - "An exception was caught while attempting to retrieve model '{}' from remote repository '{}'.Reason:{}", - model.getPath(), remoteRepository.getId(), e.getMessage() ); - } - catch ( Exception e ) - { - log.warn( - "An exception was caught while attempting to retrieve model '{}' from remote repository '{}'.Reason:{}", - model.getPath(), remoteRepository.getId(), e.getMessage() ); - - continue; - } - } - } - - return new FileModelSource( model.getFilePath().toFile() ); - } - - public ModelSource resolveModel(Parent parent) throws UnresolvableModelException { - try { - Artifact artifact = new DefaultArtifact(parent.getGroupId(), parent.getArtifactId(), "", "pom", parent.getVersion()); - VersionRangeRequest versionRangeRequest; - versionRangeRequest = new VersionRangeRequest(artifact, null, null); - VersionRangeResult versionRangeResult = this.versionRangeResolver.resolveVersionRange(this.session, versionRangeRequest); - if (versionRangeResult.getHighestVersion() == null) { - throw new UnresolvableModelException(String.format("No versions matched the requested parent version range '%s'", parent.getVersion()), parent.getGroupId(), parent.getArtifactId(), parent.getVersion()); - } else if (versionRangeResult.getVersionConstraint() != null && versionRangeResult.getVersionConstraint().getRange() != null && versionRangeResult.getVersionConstraint().getRange().getUpperBound() == null) { - throw new UnresolvableModelException(String.format("The requested parent version range '%s' does not specify an upper bound", parent.getVersion()), parent.getGroupId(), parent.getArtifactId(), parent.getVersion()); - } else { - parent.setVersion(versionRangeResult.getHighestVersion().toString()); - return this.resolveModel(parent.getGroupId(), parent.getArtifactId(), parent.getVersion()); - } - } catch ( VersionRangeResolutionException var5) { - throw new UnresolvableModelException(var5.getMessage(), parent.getGroupId(), parent.getArtifactId(), parent.getVersion(), var5); - } - } - - public ModelSource resolveModel(Dependency dependency) throws UnresolvableModelException { - try { - Artifact artifact = new DefaultArtifact(dependency.getGroupId(), dependency.getArtifactId(), "", "pom", dependency.getVersion()); - VersionRangeRequest versionRangeRequest = new VersionRangeRequest(artifact, null, null); - VersionRangeResult versionRangeResult = this.versionRangeResolver.resolveVersionRange(this.session, versionRangeRequest); - if (versionRangeResult.getHighestVersion() == null) { - throw new UnresolvableModelException(String.format("No versions matched the requested dependency version range '%s'", dependency.getVersion()), dependency.getGroupId(), dependency.getArtifactId(), dependency.getVersion()); - } else if (versionRangeResult.getVersionConstraint() != null && versionRangeResult.getVersionConstraint().getRange() != null && versionRangeResult.getVersionConstraint().getRange().getUpperBound() == null) { - throw new UnresolvableModelException(String.format("The requested dependency version range '%s' does not specify an upper bound", dependency.getVersion()), dependency.getGroupId(), dependency.getArtifactId(), dependency.getVersion()); - } else { - dependency.setVersion(versionRangeResult.getHighestVersion().toString()); - return this.resolveModel(dependency.getGroupId(), dependency.getArtifactId(), dependency.getVersion()); - } - } catch (VersionRangeResolutionException var5) { - throw new UnresolvableModelException(var5.getMessage(), dependency.getGroupId(), dependency.getArtifactId(), dependency.getVersion(), var5); - } - } - - protected Path findTimeStampedSnapshotPom( String groupId, String artifactId, String version, - Path parentDirectory ) - { - - // reading metadata if there - Path mavenMetadata = parentDirectory.resolve( METADATA_FILENAME ); - if ( Files.exists(mavenMetadata) ) - { - try - { - ArchivaRepositoryMetadata archivaRepositoryMetadata = metadataReader.read( mavenMetadata ); - SnapshotVersion snapshotVersion = archivaRepositoryMetadata.getSnapshotVersion(); - if ( snapshotVersion != null ) - { - String lastVersion = snapshotVersion.getTimestamp(); - int buildNumber = snapshotVersion.getBuildNumber(); - String snapshotPath = - StringUtils.replaceChars( groupId, '.', '/' ) + '/' + artifactId + '/' + version + '/' - + artifactId + '-' + StringUtils.remove( version, "-" + VersionUtil.SNAPSHOT ) + '-' - + lastVersion + '-' + buildNumber + ".pom"; - - log.debug( "use snapshot path {} for maven coordinate {}:{}:{}", snapshotPath, groupId, artifactId, - version ); - - StorageAsset model = basedir.resolve( snapshotPath ); - //model = pathTranslator.toFile( basedir, groupId, artifactId, lastVersion, filename ); - if ( model.exists() ) - { - return model.getFilePath(); - } - } - } - catch ( RepositoryMetadataException e ) - { - log.warn( "fail to read {}, {}", mavenMetadata.toAbsolutePath(), e.getCause() ); - } - } - - return null; - } - - @Override - public void addRepository( Repository repository ) - throws InvalidRepositoryException - { - // we just ignore repositories outside of the current one for now - // TODO: it'd be nice to look them up from Archiva's set, but we want to do that by URL / mapping, not just the - // ID since they will rarely match - } - - @Override - public void addRepository( Repository repository, boolean b ) throws InvalidRepositoryException - { - - } - - @Override - public ModelResolver newCopy() - { - return new RepositoryModelResolver( managedRepository, pathTranslator, wagonFactory, remoteRepositories, - networkProxyMap, targetRepository, mavenSystemManager, metadataReader); - } - - // FIXME: 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( RemoteRepository remoteRepository, String groupId, String artifactId, - String version, String filename ) - throws AuthorizationException, TransferFailedException, ResourceDoesNotExistException, WagonFactoryException, - IOException, RepositoryMetadataException - { - boolean success = false; - Path tmpMd5 = null; - Path tmpSha1 = null; - Path tmpResource = null; - String artifactPath = pathTranslator.toPath( groupId, artifactId, version, filename ); - Path resource = targetRepository.getRoot().getFilePath().resolve( artifactPath ); - - Path workingDirectory = createWorkingDirectory( targetRepository.getLocation().toString() ); - try - { - Wagon wagon = null; - try - { - String protocol = getProtocol( remoteRepository.getLocation().toString() ); - final NetworkProxy networkProxy = this.networkProxyMap.get( remoteRepository.getId() ); - - wagon = wagonFactory.getWagon( - new WagonFactoryRequest( "wagon#" + protocol, remoteRepository.getExtraHeaders() ).networkProxy( - networkProxy ) - ); - - if ( wagon == null ) - { - throw new RuntimeException( "Unsupported remote repository protocol: " + protocol ); - } - - boolean connected = connectToRepository( wagon, remoteRepository ); - if ( connected ) - { - tmpResource = workingDirectory.resolve( filename ); - - if ( VersionUtil.isSnapshot( version ) ) - { - // get the metadata first! - Path tmpMetadataResource = workingDirectory.resolve( METADATA_FILENAME ); - - String metadataPath = - StringUtils.substringBeforeLast( artifactPath, "/" ) + "/" + METADATA_FILENAME; - - wagon.get( addParameters( metadataPath, remoteRepository ), tmpMetadataResource.toFile() ); - - log.debug( "Successfully downloaded metadata." ); - - ArchivaRepositoryMetadata metadata = metadataReader.read( tmpMetadataResource ); - - // re-adjust to timestamp if present, otherwise retain the original -SNAPSHOT filename - SnapshotVersion snapshotVersion = metadata.getSnapshotVersion(); - String timestampVersion = version; - if ( snapshotVersion != null ) - { - timestampVersion = timestampVersion.substring( 0, timestampVersion.length() - - 8 ); // remove SNAPSHOT from end - timestampVersion = timestampVersion + snapshotVersion.getTimestamp() + "-" - + snapshotVersion.getBuildNumber(); - - filename = artifactId + "-" + timestampVersion + ".pom"; - - artifactPath = pathTranslator.toPath( groupId, artifactId, version, filename ); - - log.debug( "New artifactPath :{}", artifactPath ); - } - } - - log.info( "Retrieving {} from {}", artifactPath, remoteRepository.getName() ); - - wagon.get( addParameters( artifactPath, remoteRepository ), tmpResource.toFile() ); - - 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.toAbsolutePath().toString().intern() ) - { - Path directory = resource.getParent(); - moveFileIfExists( tmpMd5, directory ); - moveFileIfExists( tmpSha1, directory ); - moveFileIfExists( tmpResource, directory ); - success = true; - } - } - } - finally - { - org.apache.archiva.common.utils.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, RemoteRepository remoteRepository ) - { - boolean connected; - - final NetworkProxy proxyConnector = this.networkProxyMap.get( remoteRepository.getId() ); - ProxyInfo networkProxy = null; - if ( proxyConnector != null ) - { - networkProxy = new ProxyInfo(); - networkProxy.setType( proxyConnector.getProtocol() ); - networkProxy.setHost( proxyConnector.getHost() ); - networkProxy.setPort( proxyConnector.getPort() ); - networkProxy.setUserName( proxyConnector.getUsername() ); - networkProxy.setPassword( new String(proxyConnector.getPassword()) ); - - String msg = "Using network proxy " + networkProxy.getHost() + ":" + networkProxy.getPort() - + " to connect to remote repository " + remoteRepository.getLocation(); - 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; - RepositoryCredentials creds = remoteRepository.getLoginCredentials(); - String username = ""; - String password = ""; - if (creds instanceof UsernamePasswordCredentials) { - UsernamePasswordCredentials c = (UsernamePasswordCredentials) creds; - username = c.getUserName(); - password = c.getPassword(); - } - - if ( StringUtils.isNotBlank( username ) && StringUtils.isNotBlank( password ) ) - { - log.debug( "Using username {} to connect to remote repository {}", username, remoteRepository.getLocation() ); - authInfo = new AuthenticationInfo(); - authInfo.setUserName( username ); - authInfo.setPassword( password ); - } - - int timeoutInMilliseconds = ((int)remoteRepository.getTimeout().getSeconds())*1000; - // FIXME olamy having 2 config values - // Set timeout - wagon.setReadTimeout( timeoutInMilliseconds ); - wagon.setTimeout( timeoutInMilliseconds ); - - try - { - org.apache.maven.wagon.repository.Repository wagonRepository = - new org.apache.maven.wagon.repository.Repository( remoteRepository.getId(), remoteRepository.getLocation().toString() ); - if ( networkProxy != null ) - { - wagon.connect( wagonRepository, authInfo, networkProxy ); - } - else - { - wagon.connect( wagonRepository, authInfo ); - } - connected = true; - } - catch ( ConnectionException | AuthenticationException e ) - { - log.error( "Could not connect to {}:{} ", remoteRepository.getName(), e.getMessage() ); - connected = false; - } - - return connected; - } - - /** - * - * @param wagon The wagon instance that should be connected. - * @param remoteRepository The repository from where the checksum file should be retrieved - * @param remotePath The remote path of the artifact (without extension) - * @param resource The local artifact (without extension) - * @param workingDir The working directory where the downloaded file should be placed to - * @param ext The extension of th checksum file - * @return The file where the data has been downloaded to. - * @throws AuthorizationException - * @throws TransferFailedException - * @throws ResourceDoesNotExistException - */ - private Path transferChecksum( final Wagon wagon, final RemoteRepository remoteRepository, - final String remotePath, final Path resource, - final Path workingDir, final String ext ) - throws AuthorizationException, TransferFailedException, ResourceDoesNotExistException - { - Path destFile = workingDir.resolve( resource.getFileName() + ext ); - String remoteChecksumPath = remotePath + ext; - - log.info( "Retrieving {} from {}", remoteChecksumPath, remoteRepository.getName() ); - - wagon.get( addParameters( remoteChecksumPath, remoteRepository ), destFile.toFile() ); - - log.debug( "Downloaded successfully." ); - - return destFile; - } - - private String getProtocol( String url ) - { - String protocol = StringUtils.substringBefore( url, ":" ); - - return protocol; - } - - private Path createWorkingDirectory( String targetRepository ) - throws IOException - { - return Files.createTempDirectory( "temp" ); - } - - private void moveFileIfExists( Path fileToMove, Path directory ) - { - if ( fileToMove != null && Files.exists(fileToMove) ) - { - Path newLocation = directory.resolve( fileToMove.getFileName() ); - try { - Files.deleteIfExists(newLocation); - } catch (IOException e) { - throw new RuntimeException( - "Unable to overwrite existing target file: " + newLocation.toAbsolutePath(), e ); - } - - try { - Files.createDirectories(newLocation.getParent()); - } catch (IOException e) { - e.printStackTrace(); - } - try { - Files.move(fileToMove, newLocation ); - } catch (IOException e) { - try { - Files.copy(fileToMove, newLocation); - } catch (IOException e1) { - if (Files.exists(newLocation)) { - log.error( "Tried to copy file {} to {} but file with this name already exists.", - fileToMove.getFileName(), newLocation.toAbsolutePath() ); - } else { - throw new RuntimeException( - "Cannot copy tmp file " + fileToMove.toAbsolutePath() + " to its final location", e ); - } - } - } finally { - org.apache.archiva.common.utils.FileUtils.deleteQuietly(fileToMove); - } - } - } - - protected String addParameters( String path, RemoteRepository remoteRepository ) - { - if ( remoteRepository.getExtraParameters().isEmpty() ) - { - return path; - } - - boolean question = false; - - StringBuilder res = new StringBuilder( path == null ? "" : path ); - - for ( Map.Entry entry : remoteRepository.getExtraParameters().entrySet() ) - { - if ( !question ) - { - res.append( '?' ).append( entry.getKey() ).append( '=' ).append( entry.getValue() ); - } - } - - return res.toString(); - } -} diff --git a/archiva-modules/archiva-maven/archiva-maven-repository/src/main/resources/META-INF/spring-context.xml b/archiva-modules/archiva-maven/archiva-maven-repository/src/main/resources/META-INF/spring-context.xml index a01350626..7ce888983 100644 --- a/archiva-modules/archiva-maven/archiva-maven-repository/src/main/resources/META-INF/spring-context.xml +++ b/archiva-modules/archiva-maven/archiva-maven-repository/src/main/resources/META-INF/spring-context.xml @@ -28,8 +28,8 @@ default-lazy-init="true"> - + diff --git a/archiva-modules/archiva-maven/archiva-maven-repository/src/test/java/org/apache/archiva/maven/repository/AbstractRepositoryLayerTestCase.java b/archiva-modules/archiva-maven/archiva-maven-repository/src/test/java/org/apache/archiva/maven/repository/AbstractRepositoryLayerTestCase.java new file mode 100644 index 000000000..da623b8b5 --- /dev/null +++ b/archiva-modules/archiva-maven/archiva-maven-repository/src/test/java/org/apache/archiva/maven/repository/AbstractRepositoryLayerTestCase.java @@ -0,0 +1,93 @@ +package org.apache.archiva.maven.repository; + +/* + * 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.repository.ManagedRepositoryContent; +import org.apache.archiva.repository.RemoteRepositoryContent; +import org.apache.archiva.repository.RepositoryContentProvider; +import org.apache.archiva.test.utils.ArchivaSpringJUnit4ClassRunner; +import org.junit.Rule; +import org.junit.rules.TestName; +import org.junit.runner.RunWith; +import org.springframework.context.ApplicationContext; +import org.springframework.test.context.ContextConfiguration; + +import javax.inject.Inject; +import java.io.IOException; +import java.net.URI; +import java.net.URISyntaxException; +import java.nio.file.Path; +import java.nio.file.Paths; + +/** + * AbstractRepositoryLayerTestCase + * + * + */ +@RunWith( ArchivaSpringJUnit4ClassRunner.class ) +@ContextConfiguration( { "classpath*:/META-INF/spring-context.xml", "classpath:/spring-context-repository-conf.xml" } ) +public abstract class AbstractRepositoryLayerTestCase +{ + @Rule + public TestName name = new TestName(); + + @Inject + protected ApplicationContext applicationContext; + + protected MavenManagedRepository createRepository( String id, String name, Path location ) throws IOException { + MavenManagedRepository repo = MavenManagedRepository.newLocalInstance( id, name, location.getParent().toAbsolutePath()); + repo.setLocation( location.toAbsolutePath().toUri() ); + return repo; + } + + protected MavenRemoteRepository createRemoteRepository( String id, String name, String url ) throws URISyntaxException, IOException { + MavenRemoteRepository repo = MavenRemoteRepository.newLocalInstance(id, name, Paths.get("target/remotes")); + repo.setLocation( new URI( url ) ); + return repo; + } + + protected ManagedRepositoryContent createManagedRepositoryContent( String id, String name, Path location, + String layout ) + throws Exception + { + MavenManagedRepository repo = MavenManagedRepository.newLocalInstance( id, name, location.getParent() ); + repo.setLocation( location.toAbsolutePath().toUri() ); + repo.setLayout( layout ); + + RepositoryContentProvider provider = applicationContext.getBean( "repositoryContentProvider#maven", RepositoryContentProvider.class ); + ManagedRepositoryContent repoContent = + provider.createManagedContent( repo ); + + return repoContent; + } + + protected RemoteRepositoryContent createRemoteRepositoryContent( String id, String name, String url, String layout ) + throws Exception + { + MavenRemoteRepository repo = MavenRemoteRepository.newLocalInstance(id, name, Paths.get("target/remotes")); + repo.setLocation( new URI( url ) ); + repo.setLayout( layout ); + + RepositoryContentProvider provider = applicationContext.getBean( "repositoryContentProvider#maven", RepositoryContentProvider.class ); + RemoteRepositoryContent repoContent = + provider.createRemoteContent( repo ); + + return repoContent; + } +} diff --git a/archiva-modules/archiva-maven/archiva-maven-repository/src/test/java/org/apache/archiva/maven/repository/MavenRepositoryProviderTest.java b/archiva-modules/archiva-maven/archiva-maven-repository/src/test/java/org/apache/archiva/maven/repository/MavenRepositoryProviderTest.java new file mode 100644 index 000000000..dcd3b7f37 --- /dev/null +++ b/archiva-modules/archiva-maven/archiva-maven-repository/src/test/java/org/apache/archiva/maven/repository/MavenRepositoryProviderTest.java @@ -0,0 +1,373 @@ +package org.apache.archiva.maven.repository; + +/* + * 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.utils.FileUtils; +import org.apache.archiva.configuration.ArchivaRuntimeConfiguration; +import org.apache.archiva.configuration.ManagedRepositoryConfiguration; +import org.apache.archiva.configuration.RemoteRepositoryConfiguration; +import org.apache.archiva.configuration.RepositoryGroupConfiguration; +import org.apache.archiva.repository.EditableRepositoryGroup; +import org.apache.archiva.repository.ManagedRepository; +import org.apache.archiva.repository.ReleaseScheme; +import org.apache.archiva.repository.RemoteRepository; +import org.apache.archiva.repository.RepositoryException; +import org.apache.archiva.repository.RepositoryGroup; +import org.apache.archiva.repository.RepositoryRegistry; +import org.apache.archiva.repository.RepositoryType; +import org.apache.archiva.repository.UnsupportedFeatureException; +import org.apache.archiva.repository.base.PasswordCredentials; +import org.apache.archiva.repository.features.ArtifactCleanupFeature; +import org.apache.archiva.repository.features.IndexCreationFeature; +import org.apache.archiva.repository.features.RemoteIndexFeature; +import org.apache.archiva.repository.features.StagingRepositoryFeature; +import org.apache.archiva.maven.repository.metadata.storage.mock.MockConfiguration; +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + +import java.io.IOException; +import java.net.URI; +import java.net.URISyntaxException; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.time.Duration; +import java.time.Period; +import java.time.temporal.ChronoUnit; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.Map; + +import static org.junit.Assert.*; + +/** + * @author Martin Stockhammer + */ +public class MavenRepositoryProviderTest +{ + + MavenRepositoryProvider provider; + RepositoryRegistry reg; + + Path repoLocation; + + + @Before + public void setUp() + throws Exception + { + provider = new MavenRepositoryProvider( ); + MockConfiguration mockConfiguration =new MockConfiguration(); + mockConfiguration.getConfiguration().setArchivaRuntimeConfiguration( new ArchivaRuntimeConfiguration() ); + mockConfiguration.getConfiguration().getArchivaRuntimeConfiguration().setRepositoryBaseDirectory( "repositories" ); + provider.setArchivaConfiguration( mockConfiguration ); + + } + + @After + public void cleanUp() { + if (repoLocation!=null && Files.exists( repoLocation )) { + FileUtils.deleteQuietly( repoLocation ); + } + } + + @Test + public void provides( ) throws Exception + { + assertEquals(1, provider.provides().size()); + assertEquals( RepositoryType.MAVEN, provider.provides().iterator().next()); + } + + @Test + public void createManagedInstance( ) throws Exception + { + ManagedRepositoryConfiguration repo = new ManagedRepositoryConfiguration( ); + repo.setId("testm001"); + repo.setName("Managed Test Repo 001"); + repo.setDescription( "This is a managed test" ); + repo.setRetentionPeriod( 37 ); + repoLocation = Files.createTempDirectory( "test-repo-001"); + repo.setLocation( repoLocation.toAbsolutePath().toString() ); + repo.setSnapshots( true ); + repo.setReleases( true ); + repo.setRefreshCronExpression( "4 0 0 ? * TUE" ); + repo.setScanned( true ); + repo.setBlockRedeployments( true ); + repo.setDeleteReleasedSnapshots( true ); + repo.setRetentionCount( 33 ); + repo.setSkipPackedIndexCreation( true ); + repo.setStageRepoNeeded( true ); + repo.setIndexDir( "testmanaged/.index" ); + repo.setLayout( "maven2" ); + repo.setType( RepositoryType.MAVEN.toString() ); + + + ManagedRepository mr = provider.createManagedInstance( repo ); + assertNotNull(mr.getLocation()); + String repoUri = repoLocation.toUri().toString(); + assertTrue(Files.exists(repoLocation)); + repoUri = repoUri.substring( 0, repoUri.length()-1 ); + assertEquals(repoUri, mr.getLocation().toString()); + assertEquals("This is a managed test", mr.getDescription()); + assertEquals("Managed Test Repo 001", mr.getName()); + assertEquals(2, mr.getActiveReleaseSchemes().size()); + assertTrue( mr.getActiveReleaseSchemes().contains( ReleaseScheme.RELEASE )); + assertTrue( mr.getActiveReleaseSchemes().contains( ReleaseScheme.SNAPSHOT)); + assertEquals("testm001", mr.getId()); + assertTrue(mr.blocksRedeployments()); + assertEquals("4 0 0 ? * TUE", mr.getSchedulingDefinition()); + assertTrue(mr.isScanned()); + ArtifactCleanupFeature artifactCleanupFeature = mr.getFeature( ArtifactCleanupFeature.class ).get(); + assertEquals( Period.ofDays( 37), artifactCleanupFeature.getRetentionPeriod()); + assertTrue(artifactCleanupFeature.isDeleteReleasedSnapshots()); + assertEquals(33, artifactCleanupFeature.getRetentionCount()); + + IndexCreationFeature indexCreationFeature = mr.getFeature( IndexCreationFeature.class ).get(); + assertNotNull(indexCreationFeature.getIndexPath()); + assertEquals("testmanaged/.index", indexCreationFeature.getIndexPath().toString()); + assertFalse(indexCreationFeature.getIndexPath().isAbsolute()); + assertTrue(indexCreationFeature.isSkipPackedIndexCreation()); + + StagingRepositoryFeature stagingRepositoryFeature = mr.getFeature( StagingRepositoryFeature.class ).get(); + assertTrue(stagingRepositoryFeature.isStageRepoNeeded()); + assertNull(stagingRepositoryFeature.getStagingRepository()); + + + } + + @Test + public void createRemoteInstance( ) throws Exception + { + RemoteRepositoryConfiguration repo = new RemoteRepositoryConfiguration( ); + repo.setUsername("testuser001"); + repo.setPassword( "pwd0000abc" ); + repo.setCheckPath( "test/check.html" ); + repo.setTimeout( 50 ); + repo.setUrl( "https://repo.maven.apache.org/maven2/test" ); + repo.setDownloadRemoteIndex( true ); + repo.setDownloadRemoteIndexOnStartup( true ); + Map header = new HashMap<>( ); + header.put("header1","value1"); + header.put("header2","value2"); + repo.setExtraHeaders( header ); + Map params = new HashMap<>( ); + params.put("param1","pval1"); + params.put("param2","pval2"); + repo.setExtraParameters( params ); + repo.setRefreshCronExpression( "0 1 07 ? * MON" ); + repo.setRemoteDownloadTimeout( 333 ); + repo.setRemoteIndexUrl( "testremote/.index" ); + repo.setDescription( "This is a test" ); + repo.setId( "test001" ); + repo.setName( "Remote Test Repo 001" ); + repo.setIndexDir( "testindex/.index" ); + repo.setLayout( "maven2" ); + repo.setType( RepositoryType.MAVEN.toString() ); + repo.setIndexDir( "local/.index" ); + + RemoteRepository mr = provider.createRemoteInstance( repo ); + assertEquals("test001", mr.getId()); + assertEquals("This is a test", mr.getDescription()); + assertNotNull(mr.getLocation()); + assertEquals("https://repo.maven.apache.org/maven2/test", mr.getLocation().toString()); + assertEquals("Remote Test Repo 001", mr.getName()); + assertEquals("test001", mr.getId()); + assertEquals("0 1 07 ? * MON", mr.getSchedulingDefinition()); + assertEquals(50, mr.getTimeout().get( ChronoUnit.SECONDS )); + assertTrue(mr.isScanned()); + assertNotNull(mr.getLoginCredentials()); + assertTrue(mr.getLoginCredentials() instanceof PasswordCredentials ); + PasswordCredentials creds = (PasswordCredentials) mr.getLoginCredentials(); + assertEquals("testuser001", creds.getUsername()); + assertEquals("pwd0000abc", new String(creds.getPassword())); + assertEquals("value1", mr.getExtraHeaders().get("header1")); + assertEquals("pval2", mr.getExtraParameters().get("param2")); + assertEquals( "maven2", mr.getLayout()); + try + { + ArtifactCleanupFeature artifactCleanupFeature = mr.getFeature( ArtifactCleanupFeature.class ).get( ); + throw new Exception("artifactCleanupFeature should not be available"); + } catch ( UnsupportedFeatureException e ) { + // correct + } + + IndexCreationFeature indexCreationFeature = mr.getFeature( IndexCreationFeature.class ).get( ); + assertEquals("local/.index", indexCreationFeature.getIndexPath().toString()); + try + { + StagingRepositoryFeature stagingRepositoryFeature = mr.getFeature( StagingRepositoryFeature.class ).get( ); + throw new Exception("stagingRepositoryFeature should not be available"); + } catch (UnsupportedFeatureException e) { + // correct + } + RemoteIndexFeature remoteIndexFeature = mr.getFeature( RemoteIndexFeature.class ).get(); + assertNull(remoteIndexFeature.getProxyId()); + } + + @Test + public void getManagedConfiguration() throws Exception { + MavenManagedRepository repo = MavenManagedRepository.newLocalInstance( "test01", "My Test repo", Paths.get("target/repositories") ); + + repo.setLocation( new URI("target/this.is/a/test") ); + repo.setScanned( true ); + repo.setDescription( repo.getPrimaryLocale(), "This is a description" ); + repo.setLayout( "maven2" ); + repo.setBlocksRedeployment( true ); + repo.setName( repo.getPrimaryLocale(), "test0002" ); + repo.setSchedulingDefinition( "0 0 05 ? * WED" ); + repo.addActiveReleaseScheme( ReleaseScheme.RELEASE ); + repo.addActiveReleaseScheme( ReleaseScheme.SNAPSHOT ); + StagingRepositoryFeature stagingFeat = repo.getFeature( StagingRepositoryFeature.class ).get( ); + stagingFeat.setStageRepoNeeded( true ); + IndexCreationFeature indexCreationFeature = repo.getFeature( IndexCreationFeature.class ).get(); + indexCreationFeature.setIndexPath( new URI("test/.indexes") ); + indexCreationFeature.setSkipPackedIndexCreation( true ); + ArtifactCleanupFeature artifactCleanupFeature = repo.getFeature( ArtifactCleanupFeature.class ).get(); + artifactCleanupFeature.setRetentionPeriod( Period.ofDays( 5 ) ); + artifactCleanupFeature.setRetentionCount( 7 ); + artifactCleanupFeature.setDeleteReleasedSnapshots( true ); + + ManagedRepositoryConfiguration cfg = provider.getManagedConfiguration( repo ); + assertEquals("target/this.is/a/test", cfg.getLocation()); + assertTrue(cfg.isScanned()); + assertEquals( "This is a description", cfg.getDescription() ); + assertEquals("maven2", cfg.getLayout()); + assertTrue(cfg.isBlockRedeployments()); + assertEquals("test0002", cfg.getName()); + assertEquals("0 0 05 ? * WED", cfg.getRefreshCronExpression()); + assertTrue(cfg.isStageRepoNeeded()); + assertEquals("test/.indexes", cfg.getIndexDir()); + assertTrue(cfg.isSkipPackedIndexCreation()); + assertEquals(5, cfg.getRetentionPeriod()); + assertEquals(7, cfg.getRetentionCount()); + assertTrue(cfg.isDeleteReleasedSnapshots()); + assertTrue(cfg.isReleases()); + assertTrue(cfg.isSnapshots()); + assertTrue(cfg.isScanned()); + + + + } + + @Test + public void getRemoteConfiguration() throws Exception { + MavenRemoteRepository repo = MavenRemoteRepository.newLocalInstance( "test01", "My Test repo", Paths.get("target/remotes") ); + + repo.setLocation( new URI("https://this.is/a/test") ); + repo.setScanned( true ); + repo.setDescription( repo.getPrimaryLocale(), "This is a description" ); + repo.setLayout( "maven2" ); + repo.setName( repo.getPrimaryLocale(), "test0003" ); + repo.setSchedulingDefinition( "0 0 05 ? * WED" ); + RemoteIndexFeature remoteIndexFeature = repo.getFeature( RemoteIndexFeature.class ).get(); + remoteIndexFeature.setProxyId( "proxyabc" ); + remoteIndexFeature.setDownloadTimeout( Duration.ofSeconds( 54 ) ); + remoteIndexFeature.setDownloadRemoteIndex( false ); + remoteIndexFeature.setIndexUri( new URI("/this/remote/.index") ); + remoteIndexFeature.setDownloadRemoteIndexOnStartup( true ); + IndexCreationFeature indexCreationFeature = repo.getFeature( IndexCreationFeature.class ).get(); + indexCreationFeature.setIndexPath( new URI("/this/local/.index") ); + + RemoteRepositoryConfiguration cfg = provider.getRemoteConfiguration( repo ); + assertEquals("https://this.is/a/test", cfg.getUrl()); + assertEquals( "This is a description", cfg.getDescription() ); + assertEquals("maven2", cfg.getLayout()); + assertEquals("test0003", cfg.getName()); + assertEquals("0 0 05 ? * WED", cfg.getRefreshCronExpression()); + assertEquals("/this/remote/.index", cfg.getRemoteIndexUrl()); + assertEquals("proxyabc", cfg.getRemoteDownloadNetworkProxyId()); + assertEquals(54, cfg.getRemoteDownloadTimeout()); + assertFalse(cfg.isDownloadRemoteIndex()); + assertTrue(cfg.isDownloadRemoteIndexOnStartup()); + assertEquals("/this/local/.index", cfg.getIndexDir()); + + + } + + @Test + public void getRepositoryGroupConfiguration() throws RepositoryException, URISyntaxException, IOException { + MavenRepositoryGroup repositoryGroup = MavenRepositoryGroup.newLocalInstance("group1","group1",Paths.get("target/groups")); + MavenManagedRepository repo1 = MavenManagedRepository.newLocalInstance( "test01", "My Test repo", Paths.get("target/repositories") ); + MavenManagedRepository repo2 = MavenManagedRepository.newLocalInstance( "test02", "My Test repo", Paths.get("target/repositories") ); + + + repositoryGroup.setDescription(repositoryGroup.getPrimaryLocale(), "Repository group"); + repositoryGroup.setLayout("non-default"); + IndexCreationFeature indexCreationFeature = repositoryGroup.getFeature( IndexCreationFeature.class ).get(); + indexCreationFeature.setIndexPath( new URI(".index2") ); + repositoryGroup.setName(repositoryGroup.getPrimaryLocale(), "Repo Group 1"); + repositoryGroup.setMergedIndexTTL(1005); + repositoryGroup.setSchedulingDefinition("0 0 04 ? * THU"); + repositoryGroup.addRepository(repo1); + repositoryGroup.addRepository(repo2); + + + RepositoryGroupConfiguration cfg = provider.getRepositoryGroupConfiguration(repositoryGroup); + assertEquals("group1", cfg.getId()); + assertEquals(".index2", cfg.getMergedIndexPath()); + assertEquals("0 0 04 ? * THU", cfg.getCronExpression()); + assertEquals("Repo Group 1", cfg.getName()); + assertEquals(1005, cfg.getMergedIndexTtl()); + assertTrue(cfg.getRepositories().contains("test01")); + assertTrue(cfg.getRepositories().contains("test02")); + assertEquals(2, cfg.getRepositories().size()); + } + + + @Test + public void createRepositoryGroup() { + EditableRepositoryGroup gr = provider.createRepositoryGroup("group1", "Group 1"); + assertEquals("group1",gr.getId()); + assertEquals("Group 1", gr.getName()); + assertEquals(MavenRepositoryGroup.class, gr.getClass()); + } + + @Test + public void createRepositoryGroupWithCfg() throws RepositoryException { + + RepositoryGroupConfiguration cfg = new RepositoryGroupConfiguration(); + cfg.setId("group2"); + cfg.setName("Group 2"); + cfg.setCronExpression("0 0 03 ? * MON"); + cfg.setMergedIndexTtl(504); + cfg.setMergedIndexPath(".index-abc"); + ArrayList repos = new ArrayList<>(); + repos.add("test01"); + repos.add("test02"); + cfg.setRepositories(repos); + + RepositoryGroup grp = provider.createRepositoryGroup(cfg); + + assertEquals("group2", grp.getId()); + assertEquals("Group 2", grp.getName()); + assertEquals("0 0 03 ? * MON", grp.getSchedulingDefinition()); + IndexCreationFeature indexCreationFeature = grp.getFeature( IndexCreationFeature.class ).get(); + try { + assertEquals(new URI(".index-abc"), indexCreationFeature.getIndexPath()); + } catch (URISyntaxException e) { + e.printStackTrace(); + } + assertEquals(504, grp.getMergedIndexTTL()); + assertEquals(0, grp.getRepositories().size()); + // assertTrue(grp.getRepositories().stream().anyMatch(r -> "test01".equals(r.getId()))); + // assertTrue(grp.getRepositories().stream().anyMatch(r -> "test02".equals(r.getId()))); + } + +} \ No newline at end of file diff --git a/archiva-modules/archiva-maven/archiva-maven-repository/src/test/java/org/apache/archiva/maven/repository/RepositoryURLTest.java b/archiva-modules/archiva-maven/archiva-maven-repository/src/test/java/org/apache/archiva/maven/repository/RepositoryURLTest.java new file mode 100644 index 000000000..fb3b87370 --- /dev/null +++ b/archiva-modules/archiva-maven/archiva-maven-repository/src/test/java/org/apache/archiva/maven/repository/RepositoryURLTest.java @@ -0,0 +1,99 @@ +package org.apache.archiva.maven.repository; + +/* + * 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.model.RepositoryURL; +import org.apache.archiva.test.utils.ArchivaBlockJUnit4ClassRunner; +import org.junit.Test; +import org.junit.runner.RunWith; + +import java.net.MalformedURLException; + +/** + * RepositoryURLTest + * + * + */ +@RunWith( ArchivaBlockJUnit4ClassRunner.class ) +public class RepositoryURLTest + extends TestCase +{ + private void assertURL( String actualURL, String protocol, String username, String password, String hostname, + String port, String path ) + { + RepositoryURL url = new RepositoryURL( actualURL ); + + assertEquals( protocol, url.getProtocol() ); + assertEquals( username, url.getUsername() ); + assertEquals( password, url.getPassword() ); + assertEquals( hostname, url.getHost() ); + assertEquals( port, url.getPort() ); + assertEquals( path, url.getPath() ); + } + + @Test + public void testProtocolHttp() + throws MalformedURLException + { + assertURL( "http://localhost/path/to/resource.txt", "http", null, null, "localhost", null, + "/path/to/resource.txt" ); + } + + @Test + public void testProtocolWagonWebdav() + throws MalformedURLException + { + assertURL( "dav:http://localhost/path/to/resource.txt", "dav:http", null, null, "localhost", null, + "/path/to/resource.txt" ); + } + + @Test + public void testProtocolHttpWithPort() + throws MalformedURLException + { + assertURL( "http://localhost:9090/path/to/resource.txt", "http", null, null, "localhost", "9090", + "/path/to/resource.txt" ); + } + + @Test + public void testProtocolHttpWithUsername() + throws MalformedURLException + { + assertURL( "http://user@localhost/path/to/resource.txt", "http", "user", null, "localhost", null, + "/path/to/resource.txt" ); + } + + @Test + public void testProtocolHttpWithUsernamePassword() + throws MalformedURLException + { + assertURL( "http://user:pass@localhost/path/to/resource.txt", "http", "user", "pass", "localhost", null, + "/path/to/resource.txt" ); + } + + @Test + public void testProtocolHttpWithUsernamePasswordPort() + throws MalformedURLException + { + assertURL( "http://user:pass@localhost:9090/path/to/resource.txt", "http", "user", "pass", "localhost", "9090", + "/path/to/resource.txt" ); + } +} diff --git a/archiva-modules/archiva-maven/archiva-maven-repository/src/test/java/org/apache/archiva/maven/repository/content/AbstractBaseRepositoryContentLayoutTest.java b/archiva-modules/archiva-maven/archiva-maven-repository/src/test/java/org/apache/archiva/maven/repository/content/AbstractBaseRepositoryContentLayoutTest.java new file mode 100644 index 000000000..1fa2af4b7 --- /dev/null +++ b/archiva-modules/archiva-maven/archiva-maven-repository/src/test/java/org/apache/archiva/maven/repository/content/AbstractBaseRepositoryContentLayoutTest.java @@ -0,0 +1,64 @@ +package org.apache.archiva.maven.repository.content; + +/* + * 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.repository.content.BaseRepositoryContentLayout; +import org.apache.archiva.repository.content.ItemSelector; +import org.apache.archiva.repository.content.LayoutException; +import org.apache.archiva.repository.content.base.ArchivaItemSelector; +import org.junit.Test; + +import static org.junit.Assert.fail; + +/** + * Specific tests for ManagedRepositoryContent + * + * @author Martin Stockhammer + */ +public abstract class AbstractBaseRepositoryContentLayoutTest extends AbstractRepositoryContentTest +{ + + @Override + protected void assertBadPathCi( String path, String reason ) + { + super.assertBadPathCi( path, reason ); + try + { + getManaged().toItem( path ); + fail( + "toItem(path) should have thrown a LayoutException on the invalid path [" + path + "] because of [" + reason + "]" ); + } + catch ( LayoutException e ) + { + /* expected path */ + } + } + + @Test + public void testGetArtifactOnEmptyPath() throws LayoutException + { + ItemSelector selector = ArchivaItemSelector.builder( ).build( ); + try { + getManaged( ).getLayout( BaseRepositoryContentLayout.class ).getArtifact( selector ); + fail( "getArtifact(ItemSelector) with empty selector should throw IllegalArgumentException" ); + } catch (IllegalArgumentException e) { + // Good + } + } +} diff --git a/archiva-modules/archiva-maven/archiva-maven-repository/src/test/java/org/apache/archiva/maven/repository/content/AbstractRepositoryContentTest.java b/archiva-modules/archiva-maven/archiva-maven-repository/src/test/java/org/apache/archiva/maven/repository/content/AbstractRepositoryContentTest.java new file mode 100644 index 000000000..6a3f68a81 --- /dev/null +++ b/archiva-modules/archiva-maven/archiva-maven-repository/src/test/java/org/apache/archiva/maven/repository/content/AbstractRepositoryContentTest.java @@ -0,0 +1,682 @@ +package org.apache.archiva.maven.repository.content; + +/* + * 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.maven.repository.AbstractRepositoryLayerTestCase; +import org.apache.archiva.repository.ManagedRepositoryContent; +import org.apache.archiva.repository.RepositoryContent; +import org.apache.archiva.repository.content.Artifact; +import org.apache.archiva.repository.content.BaseRepositoryContentLayout; +import org.apache.archiva.repository.content.ItemSelector; +import org.apache.archiva.repository.content.LayoutException; +import org.apache.archiva.repository.content.Namespace; +import org.apache.archiva.repository.content.Project; +import org.apache.archiva.repository.content.Version; +import org.apache.archiva.repository.content.base.ArchivaItemSelector; +import org.apache.commons.lang3.StringUtils; +import org.junit.Test; + +import static org.junit.Assert.*; + +/** + * AbstractDefaultRepositoryContentTestCase + */ +public abstract class AbstractRepositoryContentTest + extends AbstractRepositoryLayerTestCase +{ + @Test + public void testBadPathMissingType() + { + assertBadPath( "invalid/invalid/1/invalid-1", "missing type" ); + assertBadPathCi( "invalid/invalid/1/invalid-1", "missing type" ); + } + + @Test + public void testBadPathReleaseInSnapshotDir() + { + assertBadPath( "invalid/invalid/1.0-SNAPSHOT/invalid-1.0.jar", + "non snapshot artifact inside of a snapshot dir" ); + assertBadPathCi( "invalid/invalid/1.0-SNAPSHOT/invalid-1.0.jar", + "non snapshot artifact inside of a snapshot dir" ); + + } + + @Test + public void testBadPathTimestampedSnapshotNotInSnapshotDir() + { + assertBadPath( "invalid/invalid/1.0-20050611.123456-1/invalid-1.0-20050611.123456-1.jar", + "Timestamped Snapshot artifact not inside of an Snapshot dir" ); + assertBadPathCi( "invalid/invalid/1.0-20050611.123456-1/invalid-1.0-20050611.123456-1.jar", + "Timestamped Snapshot artifact not inside of an Snapshot dir" ); + } + + @Test + public void testBadPathTooShort() + { + assertBadPath( "invalid/invalid-1.0.jar", "path is too short" ); + assertBadPathCi( "invalid/invalid-1.0.jar", "path is too short" ); + } + + @Test + public void testBadPathVersionMismatchA() + { + assertBadPath( "invalid/invalid/1.0/invalid-2.0.jar", "version mismatch between path and artifact" ); + assertBadPathCi( "invalid/invalid/1.0/invalid-2.0.jar", "version mismatch between path and artifact" ); + } + + @Test + public void testBadPathVersionMismatchB() + { + assertBadPath( "invalid/invalid/1.0/invalid-1.0b.jar", "version mismatch between path and artifact" ); + assertBadPathCi( "invalid/invalid/1.0/invalid-1.0b.jar", "version mismatch between path and artifact" ); + } + + @Test + public void testBadPathWrongArtifactId() + { + assertBadPath( "org/apache/maven/test/1.0-SNAPSHOT/wrong-artifactId-1.0-20050611.112233-1.jar", + "wrong artifact id" ); + assertBadPathCi( "org/apache/maven/test/1.0-SNAPSHOT/wrong-artifactId-1.0-20050611.112233-1.jar", + "wrong artifact id" ); + } + + /** + * [MRM-432] Oddball version spec. + * Example of an oddball / unusual version spec. + * + * @throws LayoutException + * + */ + @Test + public void testGoodButOddVersionSpecGanymedSsh2() + throws LayoutException + { + String groupId = "ch.ethz.ganymed"; + String artifactId = "ganymed-ssh2"; + String version = "build210"; + String classifier = null; + String type = "jar"; + String path = "ch/ethz/ganymed/ganymed-ssh2/build210/ganymed-ssh2-build210.jar"; + + assertLayout( path, groupId, artifactId, version, classifier, type ); + assertLayoutCi( path, groupId, artifactId, version, classifier, type); + } + + /** + * [MRM-432] Oddball version spec. + * Example of an oddball / unusual version spec. + * + * @throws LayoutException + * + */ + @Test + public void testGoodButOddVersionSpecJavaxComm() + throws LayoutException + { + String groupId = "javax"; + String artifactId = "comm"; + String version = "3.0-u1"; + String classifier = null; + String type = "jar"; + String path = "javax/comm/3.0-u1/comm-3.0-u1.jar"; + + assertLayout( path, groupId, artifactId, version, classifier, type ); + assertLayoutCi( path, groupId, artifactId, version, classifier, type ); + } + + /** + * Test the ejb-client type spec. + * Type specs are not a 1 to 1 map to the extension. + * This tests that effect. + * @throws LayoutException + */ + /* TODO: Re-enabled in the future. + public void testGoodFooEjbClient() + throws LayoutException + { + String groupId = "com.foo"; + String artifactId = "foo-client"; + String version = "1.0"; + String classifier = null; + String type = "ejb-client"; // oddball type-spec (should result in jar extension) + String path = "com/foo/foo-client/1.0/foo-client-1.0.jar"; + + assertLayout( path, groupId, artifactId, version, classifier, type ); + } + */ + + /** + * [MRM-432] Oddball version spec. + * Example of an oddball / unusual version spec. + * + * @throws LayoutException + * + */ + @Test + public void testGoodButOddVersionSpecJavaxPersistence() + throws LayoutException + { + String groupId = "javax.persistence"; + String artifactId = "ejb"; + String version = "3.0-public_review"; + String classifier = null; + String type = "jar"; + String path = "javax/persistence/ejb/3.0-public_review/ejb-3.0-public_review.jar"; + + /* + * The version id of "public_review" can cause problems. is it part of + * the version spec? or the classifier? + * Since the path spec below shows it in the path, then it is really + * part of the version spec. + */ + + assertLayout( path, groupId, artifactId, version, classifier, type ); + assertLayoutCi( path, groupId, artifactId, version, classifier, type ); + } + + @Test + public void testGoodComFooTool() + throws LayoutException + { + String groupId = "com.foo"; + String artifactId = "foo-tool"; + String version = "1.0"; + String classifier = null; + String type = "jar"; + String path = "com/foo/foo-tool/1.0/foo-tool-1.0.jar"; + + assertLayout( path, groupId, artifactId, version, classifier, type ); + assertLayoutCi( path, groupId, artifactId, version, classifier, type ); + } + + @Test + public void testGoodCommonsLang() + throws LayoutException + { + String groupId = "commons-lang"; + String artifactId = "commons-lang"; + String version = "2.1"; + String classifier = null; + String type = "jar"; + String path = "commons-lang/commons-lang/2.1/commons-lang-2.1.jar"; + + assertLayout( path, groupId, artifactId, version, classifier, type ); + assertLayoutCi( path, groupId, artifactId, version, classifier, type ); + } + + /** + * [MRM-486] Can not deploy artifact test.maven-arch:test-arch due to "No ArtifactID Detected" + */ + @Test + public void testGoodDashedArtifactId() + throws LayoutException + { + String groupId = "test.maven-arch"; + String artifactId = "test-arch"; + String version = "2.0.3-SNAPSHOT"; + String classifier = null; + String type = "pom"; + String path = "test/maven-arch/test-arch/2.0.3-SNAPSHOT/test-arch-2.0.3-SNAPSHOT.pom"; + + assertLayout( path, groupId, artifactId, version, classifier, type ); + assertLayoutCi( path, groupId, artifactId, version, classifier, type ); + + } + + /** + * It may seem odd, but this is a valid artifact. + */ + @Test + public void testGoodDotNotationArtifactId() + throws LayoutException + { + String groupId = "com.company.department"; + String artifactId = "com.company.department"; + String version = "0.2"; + String classifier = null; + String type = "pom"; + String path = "com/company/department/com.company.department/0.2/com.company.department-0.2.pom"; + + assertLayout( path, groupId, artifactId, version, classifier, type ); + assertLayoutCi( path, groupId, artifactId, version, classifier, type ); + } + + /** + * It may seem odd, but this is a valid artifact. + */ + @Test + public void testGoodDotNotationSameGroupIdAndArtifactId() + throws LayoutException + { + String groupId = "com.company.department"; + String artifactId = "com.company.department.project"; + String version = "0.3"; + String classifier = null; + String type = "pom"; + String path = + "com/company/department/com.company.department.project/0.3/com.company.department.project-0.3.pom"; + + assertLayout( path, groupId, artifactId, version, classifier, type ); + assertLayoutCi( path, groupId, artifactId, version, classifier, type ); + + } + + /** + * Test the classifier, and java-source type spec. + * + * @throws LayoutException + * + */ + @Test + public void testGoodFooLibSources() + throws LayoutException + { + String groupId = "com.foo.lib"; + String artifactId = "foo-lib"; + String version = "2.1-alpha-1"; + String classifier = "sources"; + String type = "java-source"; // oddball type-spec (should result in jar extension) + String path = "com/foo/lib/foo-lib/2.1-alpha-1/foo-lib-2.1-alpha-1-sources.jar"; + + assertLayout( path, groupId, artifactId, version, classifier, type ); + assertLayoutCi( path, groupId, artifactId, version, classifier, type ); + + } + + /** + * A timestamped versioned artifact, should reside in a SNAPSHOT baseversion directory. + * + * @throws LayoutException + * + */ + @Test + public void testGoodSnapshotMavenTest() + throws LayoutException + { + String groupId = "org.apache.archiva.test"; + String artifactId = "redonkulous"; + String artifactVersion = "3.1-beta-1-20050831.101112-42"; + String version = "3.1-beta-1-SNAPSHOT"; + String classifier = null; + String type = "jar"; + String path = + "org/apache/archiva/test/redonkulous/3.1-beta-1-SNAPSHOT/redonkulous-3.1-beta-1-20050831.101112-42.jar"; + + assertLayout( path, groupId, artifactId, version, artifactVersion, classifier, type ); + assertLayoutCi( path, groupId, artifactId, version, artifactVersion, classifier, type ); + } + + /** + * [MRM-519] version identifiers within filename cause misidentification of version. + * Example uses "test" in artifact Id, which is also part of the versionKeyword list. + */ + @Test + public void testGoodVersionKeywordInArtifactId() + throws LayoutException + { + String groupId = "maven"; + String artifactId = "maven-test-plugin"; + String version = "1.8.2"; + String classifier = null; + String type = "pom"; + String path = "maven/maven-test-plugin/1.8.2/maven-test-plugin-1.8.2.pom"; + + assertLayout( path, groupId, artifactId, version, classifier, type ); + assertLayoutCi( path, groupId, artifactId, version, classifier, type ); + } + + /** + * [MRM-562] Artifact type "maven-plugin" is not detected correctly in .toArtifactReference() methods. + * Example uses "test" in artifact Id, which is also part of the versionKeyword list. + */ + @Test + public void testGoodDetectMavenTestPlugin() + throws LayoutException + { + String groupId = "maven"; + String artifactId = "maven-test-plugin"; + String version = "1.8.2"; + String classifier = null; + String type = "maven-plugin"; + String path = "maven/maven-test-plugin/1.8.2/maven-test-plugin-1.8.2.jar"; + + assertLayout( path, groupId, artifactId, version, classifier, type ); + assertLayoutCi( path, groupId, artifactId, version, classifier, type ); + + } + + /** + * [MRM-562] Artifact type "maven-plugin" is not detected correctly in .toArtifactReference() methods. + */ + @Test + public void testGoodDetectCoberturaMavenPlugin() + throws LayoutException + { + String groupId = "org.codehaus.mojo"; + String artifactId = "cobertura-maven-plugin"; + String version = "2.1"; + String classifier = null; + String type = "maven-plugin"; + String path = "org/codehaus/mojo/cobertura-maven-plugin/2.1/cobertura-maven-plugin-2.1.jar"; + + assertLayout( path, groupId, artifactId, version, classifier, type ); + assertLayoutCi( path, groupId, artifactId, version, classifier, type ); + } + + + @Test + public void testToItemSelectorOnEmptyPath() + { + try + { + getContent( ).toItemSelector( "" ); + fail( "toItemSelector() should have failed due to empty path." ); + } + catch ( LayoutException e ) + { + /* expected path */ + } + } + + @Test + public void testToArtifactOnEmptyPath() + { + try + { + toItemSelector( "" ); + fail( "Should have failed due to empty path." ); + } + catch ( LayoutException e ) + { + /* expected path */ + } + } + + @Test + public void testToArtifactOnNullPath() + { + try + { + toItemSelector( null ); + fail( "Should have failed due to null path." ); + } + catch ( LayoutException e ) + { + /* expected path */ + } + } + + @Test + public void testToItemSelectorOnNullPath() + { + try + { + getContent().toItemSelector( null ); + fail( "toItemSelector() should have failed due to null path." ); + } + catch ( LayoutException e ) + { + /* expected path */ + } + } + + @Test + public void testToPathOnNullArtifactReference() + + { + try + { + ItemSelector reference = null; + toPath( reference ); + fail( "Should have failed due to null artifact reference." ); + } + catch ( IllegalArgumentException e ) + { + /* expected path */ + } + } + + public void testToPathOnNullItemSelector() + + { + try + { + ItemSelector selector = null; + toPath( selector ); + fail( "Should have failed due to null artifact reference." ); + } + catch ( IllegalArgumentException e ) + { + /* expected path */ + } + } + + private void assertArtifactReference( ItemSelector actualReference, String groupId, String artifactId, + String version, String artifactVersion, String classifier, String type ) + { + String expectedId = + "ArtifactReference - " + groupId + ":" + artifactId + ":" + version + ":" + classifier + ":" + type; + + assertNotNull( expectedId + " - Should not be null.", actualReference ); + + assertEquals( expectedId + " - Group ID", groupId, actualReference.getNamespace() ); + assertEquals( expectedId + " - Artifact ID", artifactId, actualReference.getArtifactId() ); + if ( StringUtils.isNotBlank( classifier ) ) + { + assertEquals( expectedId + " - Classifier", classifier, actualReference.getClassifier() ); + } + assertEquals( expectedId + " - Version ID", version, actualReference.getVersion() ); + assertEquals( expectedId + " - Artifact Version ID", artifactVersion, actualReference.getArtifactVersion() ); + assertEquals( expectedId + " - Type", type, actualReference.getType() ); + } + + private void assertItemSelector( ItemSelector actualReference, String groupId, String artifactId, + String version, String artifactVersion, String classifier, String type ) + { + String expectedId = + "ArtifactReference - " + groupId + ":" + artifactId + ":" + version + ":" + classifier + ":" + type; + + assertNotNull( expectedId + " - Should not be null.", actualReference ); + + assertEquals( expectedId + " - Group ID", groupId, actualReference.getNamespace() ); + assertEquals( expectedId + " - Artifact ID", artifactId, actualReference.getArtifactId() ); + if ( StringUtils.isNotBlank( classifier ) ) + { + assertEquals( expectedId + " - Classifier", classifier, actualReference.getClassifier() ); + } + assertEquals( expectedId + " - Version ID", version, actualReference.getVersion() ); + assertEquals( expectedId + " - Artifact Version ID", artifactVersion, actualReference.getArtifactVersion() ); + assertEquals( expectedId + " - Type", type, actualReference.getType() ); + } + + private void assertBadPath( String path, String reason ) + { + try + { + toItemSelector( path ); + fail( + "Should have thrown a LayoutException on the invalid path [" + path + "] because of [" + reason + "]" ); + } + catch ( LayoutException e ) + { + /* expected path */ + } + } + + protected void assertBadPathCi( String path, String reason ) + { + try + { + toItemSelector( path ); + fail( + "Should have thrown a LayoutException on the invalid path [" + path + "] because of [" + reason + "]" ); + } + catch ( LayoutException e ) + { + /* expected path */ + } + } + + /** + * Perform a roundtrip through the layout routines to determine success. + */ + private void assertLayout( String path, String groupId, String artifactId, String version, String classifier, + String type ) + throws LayoutException + { + ItemSelector expectedArtifact = createItemSelector( groupId, artifactId, version, classifier, type ); + + // --- Artifact Tests. + + // Artifact to Path + assertEquals( "Artifact <" + expectedArtifact + "> to path:", path, toPath( expectedArtifact ) ); + + // --- Artifact Reference Tests + + // Path to Artifact Reference. + ItemSelector testReference = toItemSelector( path ); + assertArtifactReference( testReference, groupId, artifactId, version, version, classifier, type ); + + // And back again, using test Reference from previous step. + assertEquals( "Artifact <" + expectedArtifact + "> to path:", path, toPath( testReference ) ); + } + + /** + * Perform a roundtrip through the layout routines to determine success. + */ + private void assertLayout( String path, String groupId, String artifactId, String version, String artifactVersion, String classifier, + String type ) + throws LayoutException + { + ItemSelector expectedArtifact = createItemSelector( groupId, artifactId, version, artifactVersion, classifier, type ); + + // --- Artifact Tests. + + // Artifact to Path + assertEquals( "Artifact <" + expectedArtifact + "> to path:", path, toPath( expectedArtifact ) ); + + // --- Artifact Reference Tests + + // Path to Artifact Reference. + ItemSelector testReference = toItemSelector( path ); + assertArtifactReference( testReference, groupId, artifactId, version, artifactVersion, classifier, type ); + + // And back again, using test Reference from previous step. + assertEquals( "Artifact <" + expectedArtifact + "> to path:", path, toPath( testReference ) ); + } + + private void assertLayoutCi( String path, String groupId, String artifactId, String version, String classifier, + String type ) throws LayoutException + { + assertLayoutCi( path, groupId, artifactId, version, version, classifier, type ); + } + private void assertLayoutCi( String path, String groupId, String artifactId, String version, String artifactVersion, + String classifier, String type ) + throws LayoutException + { + ItemSelector expectedArtifact = createItemSelector( groupId, artifactId, version, artifactVersion, classifier, type ); + + // --- Artifact Tests. + + // Artifact to Path + assertEquals( "Artifact <" + expectedArtifact + "> to path:", path, toPath( expectedArtifact ) ); + + // --- Artifact Reference Tests + + // Path to Artifact Reference. + ItemSelector testReference = toItemSelector( path ); + assertItemSelector( testReference, groupId, artifactId, version, artifactVersion, classifier, type ); + + // And back again, using test Reference from previous step. + assertEquals( "Artifact <" + expectedArtifact + "> to path:", path, toPath( testReference ) ); + + if (getManaged()!=null) + { + Namespace ns = null; + Project pr = null; + Version ver = null; + if ( StringUtils.isNotEmpty( groupId ) ) + { + ns = getManaged( ).getLayout( BaseRepositoryContentLayout.class ).getNamespace( expectedArtifact ); + assertNotNull( ns ); + assertEquals( groupId, ns.getId( ) ); + } + if ( StringUtils.isNotEmpty( artifactId ) ) + { + pr = getManaged( ).getLayout( BaseRepositoryContentLayout.class ).getProject( expectedArtifact ); + assertNotNull( pr ); + assertEquals( artifactId, pr.getId( ) ); + assertEquals( ns, pr.getNamespace( ) ); + } + if ( StringUtils.isNotEmpty( version ) ) + { + ver = getManaged( ).getLayout( BaseRepositoryContentLayout.class ).getVersion( expectedArtifact ); + assertNotNull( ver ); + assertEquals( version, ver.getId( ) ); + assertEquals( pr, ver.getProject( ) ); + } + Artifact artifact = getManaged( ).getLayout( BaseRepositoryContentLayout.class ).getArtifact( expectedArtifact ); + assertNotNull( artifact ); + assertEquals( artifactId, artifact.getId( ) ); + assertEquals( ver, artifact.getVersion( ) ); + } + + } + + + abstract protected Artifact createArtifact( String groupId, String artifactId, String version, String classifier, + String type ) throws LayoutException; + + protected ItemSelector createItemSelector(String groupId, String artifactId, String version, String classifier, + String type) { + return ArchivaItemSelector.builder( ).withNamespace( groupId ) + .withProjectId( artifactId ) + .withArtifactId( artifactId ) + .withVersion( version ) + .withClassifier( classifier ) + .withType( type ) + .build( ); + + } + + protected ItemSelector createItemSelector(String groupId, String artifactId, String version, String artifactVersion, + String classifier, String type) { + return ArchivaItemSelector.builder( ).withNamespace( groupId ) + .withProjectId( artifactId ) + .withArtifactId( artifactId ) + .withVersion( version ) + .withArtifactVersion( artifactVersion ) + .withClassifier( classifier ) + .withType( type ) + .build( ); + + } + + + protected abstract String toPath( Artifact reference ) throws LayoutException; + + + protected abstract String toPath( ItemSelector selector ); + + protected abstract ItemSelector toItemSelector(String path) throws LayoutException; + + protected abstract ManagedRepositoryContent getManaged(); + + protected abstract RepositoryContent getContent( ); +} diff --git a/archiva-modules/archiva-maven/archiva-maven-repository/src/test/java/org/apache/archiva/maven/repository/content/ArtifactExtensionMappingTest.java b/archiva-modules/archiva-maven/archiva-maven-repository/src/test/java/org/apache/archiva/maven/repository/content/ArtifactExtensionMappingTest.java new file mode 100644 index 000000000..5281ce326 --- /dev/null +++ b/archiva-modules/archiva-maven/archiva-maven-repository/src/test/java/org/apache/archiva/maven/repository/content/ArtifactExtensionMappingTest.java @@ -0,0 +1,82 @@ +package org.apache.archiva.maven.repository.content; + +/* + * 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.maven.metadata.model.MavenArtifactFacet; +import org.apache.archiva.maven.repository.metadata.storage.ArtifactMappingProvider; +import org.apache.archiva.maven.repository.metadata.storage.Maven2RepositoryPathTranslator; +import org.apache.archiva.metadata.model.ArtifactMetadata; +import org.apache.archiva.metadata.repository.storage.RepositoryPathTranslator; +import org.apache.archiva.test.utils.ArchivaSpringJUnit4ClassRunner; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.test.context.ContextConfiguration; + +import java.util.Collections; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; + +/** + * ArtifactExtensionMappingTest + * + * + */ +@RunWith ( ArchivaSpringJUnit4ClassRunner.class ) +@ContextConfiguration ( { "classpath*:/META-INF/spring-context.xml", "classpath:/spring-context.xml" } ) +public class ArtifactExtensionMappingTest +{ + private RepositoryPathTranslator pathTranslator = new Maven2RepositoryPathTranslator( + Collections.emptyList() ); + + @Test + public void testIsMavenPlugin() + { + assertMavenPlugin( "maven-test-plugin" ); + assertMavenPlugin( "maven-clean-plugin" ); + assertMavenPlugin( "cobertura-maven-plugin" ); + assertMavenPlugin( "maven-project-info-reports-plugin" ); + assertMavenPlugin( "silly-name-for-a-maven-plugin" ); + + assertNotMavenPlugin( "maven-plugin-api" ); + assertNotMavenPlugin( "foo-lib" ); + assertNotMavenPlugin( "another-maven-plugin-api" ); + assertNotMavenPlugin( "secret-maven-plugin-2" ); + } + + private void assertMavenPlugin( String artifactId ) + { + assertEquals( "Should be detected as maven plugin: <" + artifactId + ">", "maven-plugin", getTypeFromArtifactId( + artifactId ) ); + } + + private String getTypeFromArtifactId( String artifactId ) + { + ArtifactMetadata artifact = pathTranslator.getArtifactFromId( null, "groupId", artifactId, "1.0", + artifactId + "-1.0.jar" ); + MavenArtifactFacet facet = (MavenArtifactFacet) artifact.getFacet( MavenArtifactFacet.FACET_ID ); + return facet.getType(); + } + + private void assertNotMavenPlugin( String artifactId ) + { + assertFalse( "Should NOT be detected as maven plugin: <" + artifactId + ">", "maven-plugin".equals( + getTypeFromArtifactId( artifactId ) ) ); + } +} diff --git a/archiva-modules/archiva-maven/archiva-maven-repository/src/test/java/org/apache/archiva/maven/repository/content/FilenameParserTest.java b/archiva-modules/archiva-maven/archiva-maven-repository/src/test/java/org/apache/archiva/maven/repository/content/FilenameParserTest.java new file mode 100644 index 000000000..bbda8b0ca --- /dev/null +++ b/archiva-modules/archiva-maven/archiva-maven-repository/src/test/java/org/apache/archiva/maven/repository/content/FilenameParserTest.java @@ -0,0 +1,216 @@ +package org.apache.archiva.maven.repository.content; + +/* + * 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.test.utils.ArchivaBlockJUnit4ClassRunner; +import org.junit.Test; +import org.junit.runner.RunWith; + +/** + * FilenameParserTest + * + * + */ +@RunWith( ArchivaBlockJUnit4ClassRunner.class ) +public class FilenameParserTest + extends TestCase +{ + @Test + public void testNameExtensionJar() + { + FilenameParser parser = new FilenameParser( "maven-test-plugin-1.8.3.jar" ); + + assertEquals( "maven-test-plugin-1.8.3", parser.getName() ); + assertEquals( "jar", parser.getExtension() ); + } + + @Test + public void testNameExtensionTarGz() + { + FilenameParser parser = new FilenameParser( "archiva-1.0-beta-2-bin.tar.gz" ); + + assertEquals( "archiva-1.0-beta-2-bin", parser.getName() ); + assertEquals( "tar.gz", parser.getExtension() ); + } + + @Test + public void testNameExtensionTarBz2() + { + FilenameParser parser = new FilenameParser( "archiva-1.0-SNAPSHOT-src.tar.bz2" ); + + assertEquals( "archiva-1.0-SNAPSHOT-src", parser.getName() ); + assertEquals( "tar.bz2", parser.getExtension() ); + } + + @Test + public void testNameExtensionCapitolizedTarGz() + { + FilenameParser parser = new FilenameParser( "ARCHIVA-1.0-BETA-2-BIN.TAR.GZ" ); + + assertEquals( "ARCHIVA-1.0-BETA-2-BIN", parser.getName() ); + assertEquals( "TAR.GZ", parser.getExtension() ); + } + + @Test + public void testNext() + { + FilenameParser parser = new FilenameParser( "maven-test-plugin-1.8.3.jar" ); + + assertEquals( "maven-test-plugin-1.8.3", parser.getName() ); + assertEquals( "jar", parser.getExtension() ); + + assertEquals( "maven", parser.next() ); + assertEquals( "test", parser.next() ); + assertEquals( "plugin", parser.next() ); + assertEquals( "1.8.3", parser.next() ); + assertNull( parser.next() ); + } + + @Test + public void testExpect() + { + FilenameParser parser = new FilenameParser( "maven-test-plugin-1.8.3.jar" ); + + assertEquals( "maven-test-plugin-1.8.3", parser.getName() ); + assertEquals( "jar", parser.getExtension() ); + + assertEquals( "maven-test-plugin", parser.expect( "maven-test-plugin" ) ); + assertEquals( "1.8.3", parser.expect( "1.8.3" ) ); + assertNull( parser.expect( "jar" ) ); + } + + @Test + public void testExpectWithRemaining() + { + FilenameParser parser = new FilenameParser( "ganymede-ssh2-build250-sources.jar" ); + + assertEquals( "ganymede-ssh2-build250-sources", parser.getName() ); + assertEquals( "jar", parser.getExtension() ); + + assertEquals( "ganymede-ssh2", parser.expect( "ganymede-ssh2" ) ); + assertEquals( "build250", parser.expect( "build250" ) ); + assertEquals( '-', parser.seperator() ); + assertEquals( "sources", parser.remaining() ); + + assertNull( parser.expect( "jar" ) ); + } + + @Test + public void testExpectWithRemainingDualExtensions() + { + FilenameParser parser = new FilenameParser( "example-presentation-3.2.xml.zip" ); + + assertEquals( "example-presentation-3.2.xml", parser.getName() ); + assertEquals( "zip", parser.getExtension() ); + + assertEquals( "example-presentation", parser.expect( "example-presentation" ) ); + assertEquals( "3.2", parser.expect( "3.2" ) ); + assertEquals( '.', parser.seperator() ); + assertEquals( "xml", parser.remaining() ); + + } + + @Test + public void testNextNonVersion() + { + FilenameParser parser = new FilenameParser( "maven-test-plugin-1.8.3.jar" ); + + assertEquals( "maven-test-plugin", parser.nextNonVersion() ); + assertEquals( "1.8.3", parser.remaining() ); + } + + @Test + public void testNextArbitraryNonVersion() + { + FilenameParser parser = new FilenameParser( "maven-jdk-1.4-plugin-1.0-20070828.123456-42.jar" ); + + assertEquals( "maven-jdk-1.4-plugin", parser.nextNonVersion() ); + assertEquals( "1.0-20070828.123456-42", parser.remaining() ); + } + + @Test + public void testNextJython() + { + FilenameParser parser = new FilenameParser( "jython-20020827-no-oro.jar" ); + + assertEquals( "jython", parser.nextNonVersion() ); + assertEquals( "20020827", parser.nextVersion() ); + assertEquals( "no-oro", parser.remaining() ); + } + + @Test + public void testLongExtension() + { + FilenameParser parser = new FilenameParser( "libfobs4jmf-0.4.1.4-20080217.211715-4.jnilib" ); + + assertEquals( "libfobs4jmf-0.4.1.4-20080217.211715-4", parser.getName() ); + assertEquals( "jnilib", parser.getExtension() ); + } + + @Test + public void testInterveningVersion() + { + FilenameParser parser = new FilenameParser( "artifact-id-1.0-abc-1.1-20080221.062205-9.pom" ); + + assertEquals( "artifact-id", parser.nextNonVersion() ); + assertEquals( "1.0-abc-1.1-20080221.062205-9", parser.expect( "1.0-abc-1.1-SNAPSHOT" ) ); + assertNull( null, parser.remaining() ); + assertEquals( "artifact-id-1.0-abc-1.1-20080221.062205-9", parser.getName() ); + assertEquals( "pom", parser.getExtension() ); + } + + @Test + public void testExpectWrongSnapshot() + { + FilenameParser parser = new FilenameParser( "artifact-id-1.0-20080221.062205-9.pom" ); + + assertEquals( "artifact-id", parser.nextNonVersion() ); + assertNull( parser.expect( "2.0-SNAPSHOT" ) ); + } + + @Test + public void testExpectWrongSnapshot2() + { + // tests parsing axiom snapshots without exceptions + FilenameParser parser = new FilenameParser( "axiom-20080221.062205-9.pom" ); + + assertEquals( "axiom", parser.nextNonVersion() ); + assertNull( parser.expect( "SNAPSHOT" ) ); + } + + @Test + public void testClassifier() + { + FilenameParser parser = new FilenameParser( "artifact-id-1.0-20070219.171202-34-test-sources.jar" ); + + assertEquals( "artifact-id", parser.nextNonVersion() ); + assertEquals( "1.0-20070219.171202-34", parser.nextVersion() ); + assertEquals( "test-sources", parser.remaining() ); + assertEquals( "artifact-id-1.0-20070219.171202-34-test-sources", parser.getName() ); + assertEquals( "jar", parser.getExtension() ); + } + + @Test + public void testNoExtension() + { + FilenameParser parser = new FilenameParser( "foo_bar" ); + assertNull( parser.getExtension() ); + } +} diff --git a/archiva-modules/archiva-maven/archiva-maven-repository/src/test/java/org/apache/archiva/maven/repository/content/ManagedDefaultRepositoryContentTest.java b/archiva-modules/archiva-maven/archiva-maven-repository/src/test/java/org/apache/archiva/maven/repository/content/ManagedDefaultRepositoryContentTest.java new file mode 100644 index 000000000..83930a1cd --- /dev/null +++ b/archiva-modules/archiva-maven/archiva-maven-repository/src/test/java/org/apache/archiva/maven/repository/content/ManagedDefaultRepositoryContentTest.java @@ -0,0 +1,1507 @@ +package org.apache.archiva.maven.repository.content; + +/* + * 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.filelock.FileLockManager; +import org.apache.archiva.common.utils.VersionComparator; +import org.apache.archiva.configuration.ArchivaConfiguration; +import org.apache.archiva.configuration.FileType; +import org.apache.archiva.configuration.FileTypes; +import org.apache.archiva.maven.metadata.MavenMetadataReader; +import org.apache.archiva.maven.repository.MavenManagedRepository; +import org.apache.archiva.maven.repository.metadata.storage.ArtifactMappingProvider; +import org.apache.archiva.metadata.repository.storage.RepositoryPathTranslator; +import org.apache.archiva.repository.EditableManagedRepository; +import org.apache.archiva.repository.ManagedRepository; +import org.apache.archiva.repository.ManagedRepositoryContent; +import org.apache.archiva.repository.RepositoryContent; +import org.apache.archiva.repository.content.Artifact; +import org.apache.archiva.repository.content.BaseArtifactTypes; +import org.apache.archiva.repository.content.BaseRepositoryContentLayout; +import org.apache.archiva.repository.content.ContentItem; +import org.apache.archiva.repository.content.DataItem; +import org.apache.archiva.repository.content.ItemNotFoundException; +import org.apache.archiva.repository.content.ItemSelector; +import org.apache.archiva.repository.content.LayoutException; +import org.apache.archiva.repository.content.Namespace; +import org.apache.archiva.repository.content.Project; +import org.apache.archiva.repository.content.Version; +import org.apache.archiva.repository.content.base.ArchivaContentItem; +import org.apache.archiva.repository.content.base.ArchivaItemSelector; +import org.apache.archiva.repository.storage.StorageAsset; +import org.apache.commons.io.FileUtils; +import org.junit.Before; +import org.junit.Test; + +import javax.inject.Inject; +import javax.inject.Named; +import java.io.IOException; +import java.io.OutputStream; +import java.io.Reader; +import java.net.URISyntaxException; +import java.nio.charset.Charset; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.nio.file.attribute.FileTime; +import java.util.List; +import java.util.stream.Collectors; +import java.util.stream.Stream; + +import static org.junit.Assert.*; + +/** + * ManagedDefaultRepositoryContentTest + */ +public class ManagedDefaultRepositoryContentTest + extends AbstractBaseRepositoryContentLayoutTest +{ + private ManagedDefaultRepositoryContent repoContent; + + @Inject + FileTypes fileTypes; + + @Inject + @Named ( "archivaConfiguration#default" ) + ArchivaConfiguration archivaConfiguration; + + @Inject + List artifactMappingProviders; + + @Inject + MavenContentHelper contentHelper; + + @Inject + @Named( "metadataReader#maven" ) + MavenMetadataReader metadataReader; + + @Inject + FileLockManager fileLockManager; + + @Inject + @Named( "repositoryPathTranslator#maven2" ) + RepositoryPathTranslator pathTranslator; + + + private Path getRepositoryPath(String repoName) { + try + { + return Paths.get( Thread.currentThread( ).getContextClassLoader( ).getResource( "repositories/" + repoName ).toURI( ) ); + } + catch ( URISyntaxException e ) + { + throw new RuntimeException( "Could not resolve repository path " + e.getMessage( ), e ); + } + } + + @Before + public void setUp() + throws Exception + { + Path repoDir = getRepositoryPath( "default-repository" ); + + MavenManagedRepository repository = createRepository( "testRepo", "Unit Test Repo", repoDir ); + + FileType fileType = archivaConfiguration.getConfiguration().getRepositoryScanning().getFileTypes().get( 0 ); + fileType.addPattern( "**/*.xml" ); + assertEquals( FileTypes.ARTIFACTS, fileType.getId() ); + + fileTypes.afterConfigurationChange( null, "fileType", null ); + + repoContent = new ManagedDefaultRepositoryContent(repository, fileTypes, fileLockManager); + repoContent.setMavenContentHelper( contentHelper ); + repoContent.setMetadataReader( metadataReader ); + repoContent.setPathTranslator( pathTranslator ); + repoContent.setArtifactMappingProviders( artifactMappingProviders ); + + //repoContent = (ManagedRepositoryContent) lookup( ManagedRepositoryContent.class, "default" ); + } + + @Test + public void testGetVersionsSnapshotA() + throws Exception + { + assertArtifactVersions( "snap_shots_a", "1.0-alpha-11-SNAPSHOT", + new String[]{ "1.0-alpha-11-SNAPSHOT", "1.0-alpha-11-20070221.194724-2", + "1.0-alpha-11-20070302.212723-3", "1.0-alpha-11-20070303.152828-4", + "1.0-alpha-11-20070305.215149-5", "1.0-alpha-11-20070307.170909-6", + "1.0-alpha-11-20070314.211405-9", "1.0-alpha-11-20070316.175232-11" } ); + } + + + @Test + @Override + public void testToPathOnNullArtifactReference() + { + try + { + ItemSelector reference = null; + repoContent.toPath( reference ); + fail( "Should have failed due to null artifact reference." ); + } + catch ( IllegalArgumentException e ) + { + /* expected path */ + } + } + + @Override + protected Artifact createArtifact( String groupId, String artifactId, String version, String classifier, String type ) throws LayoutException + { + ItemSelector selector = createItemSelector( groupId, artifactId, version, classifier, type ); + return repoContent.getLayout( BaseRepositoryContentLayout.class ).getArtifact( selector ); + } + + @Test + public void testExcludeMetadataFile() + throws Exception + { + assertVersions( "include_xml", "1.0", new String[]{ "1.0" } ); + } + + + private void assertVersions( String artifactId, String version, String[] expectedVersions ) + throws Exception + { + // Use the test metadata-repository, which is already setup for + // These kind of version tests. + Path repoDir = getRepositoryPath( "metadata-repository" ); + ((EditableManagedRepository)repoContent.getRepository()).setLocation( repoDir.toAbsolutePath().toUri() ); + + // Request the versions. + + // Sort the list (for asserts later) + final VersionComparator comparator = new VersionComparator( ); + + ItemSelector selector = ArchivaItemSelector.builder( ) + .withNamespace( "org.apache.archiva.metadata.tests" ) + .withProjectId( artifactId ) + .withVersion( version ) + .build( ); + List versions = repoContent.getVersions( selector ).stream() + .map(v -> v.getId()).sorted( comparator ).collect( Collectors.toList()); + assertArrayEquals( expectedVersions, versions.toArray( ) ); + + + } + + private void assertArtifactVersions( String artifactId, String version, String[] expectedVersions ) + throws Exception + { + // Use the test metadata-repository, which is already setup for + // These kind of version tests. + Path repoDir = getRepositoryPath( "metadata-repository" ); + ((EditableManagedRepository)repoContent.getRepository()).setLocation( repoDir.toAbsolutePath().toUri() ); + + // Request the versions. + + // Sort the list (for asserts later) + final VersionComparator comparator = new VersionComparator( ); + + ItemSelector selector = ArchivaItemSelector.builder( ) + .withNamespace( "org.apache.archiva.metadata.tests" ) + .withProjectId( artifactId ) + .withVersion( version ) + .build( ); + List versions = repoContent.getArtifactVersions( selector ).stream() + .sorted( comparator ).collect( Collectors.toList()); + assertArrayEquals( expectedVersions, versions.toArray( ) ); + + + } + + @Test + public void getTestGetProjectWithIllegalArgs() { + ItemSelector selector = ArchivaItemSelector.builder( ) + .withNamespace( "org.apache" ) + .withVersion( "1.0" ) + .build(); + try + { + repoContent.getProject( selector ); + assertFalse( "Should throw IllegalArgumentException if no project id is given", true ); + } catch (IllegalArgumentException e) { + // Everything fine + assertTrue( e.getMessage( ).contains( "Project id must be set" ) ); + } + } + + @Test + public void getTestGetVersionWithIllegalArgs() { + ItemSelector selector = ArchivaItemSelector.builder( ) + .withNamespace( "org.apache.maven" ) + .withVersion( "1.0" ) + .build(); + try + { + repoContent.getVersion( selector ); + assertFalse( "Should throw IllegalArgumentException if no project id is given", true ); + } catch (IllegalArgumentException e) { + // Everything fine + assertTrue( e.getMessage( ).contains( "Project id must be set" ) ); + } + + + selector = ArchivaItemSelector.builder( ) + .withNamespace( "org.apache.maven" ) + .withProjectId( "shared" ) + .build(); + try + { + repoContent.getVersion( selector ); + assertFalse( "Should throw IllegalArgumentException if no version is given", true ); + } catch (IllegalArgumentException e) { + // Everything fine + assertTrue( e.getMessage( ).contains( "Version must be set" ) ); + } + } + + @Test + public void getTestGetArtifactWithIllegalArgs() { + ItemSelector selector = ArchivaItemSelector.builder( ) + .withNamespace( "org.apache.maven" ) + .withVersion( "1.0" ) + .withArtifactId( "shared" ) + .withArtifactVersion("1.0") + .build(); + try + { + repoContent.getArtifact( selector ); + assertFalse( "Should throw IllegalArgumentException if no project id is given", true ); + } catch (IllegalArgumentException e) { + // Everything fine + assertTrue( e.getMessage( ).contains( "Project id must be set" ) ); + } + + + selector = ArchivaItemSelector.builder( ) + .withNamespace( "org.apache.maven" ) + .withProjectId( "shared" ) + .withArtifactId( "shared" ) + .build(); + try + { + repoContent.getArtifact( selector ); + assertFalse( "Should throw IllegalArgumentException if no version is given", true ); + } catch (IllegalArgumentException e) { + // Everything fine + assertTrue( e.getMessage( ).contains( "Version must be set" ) ); + } + + selector = ArchivaItemSelector.builder( ) + .withNamespace( "org.apache.maven" ) + .withProjectId( "shared" ) + .withVersion("1.0") + .withArtifactVersion("1.0") + .build(); + try + { + repoContent.getArtifact( selector ); + assertFalse( "Should throw IllegalArgumentException if no artifact id is given", true ); + } catch (IllegalArgumentException e) { + // Everything fine + assertTrue( e.getMessage( ).contains( "Artifact id must be set" ) ); + } + + + } + + @Test + public void testGetProjects() { + ItemSelector selector = ArchivaItemSelector.builder( ) + .withNamespace( "org.apache.maven" ).build(); + Namespace ns = repoContent.getNamespace( selector ); + assertNotNull( ns ); + List projects = repoContent.getProjects( ns ); + assertEquals( 12, projects.size( ) ); + String[] expected = new String[]{ + "A", "B", "C", "archiva", "discovery", "maven-parent", "samplejar", "shared", "some-ejb", "test", + "testing", "update" + }; + Object[] actual = projects.stream( ).map( p -> p.getId( ) ).sorted( ).toArray( ); + assertArrayEquals( expected, actual); + } + + @Test + public void testGetProjectsWithSelector() { + ItemSelector selector = ArchivaItemSelector.builder( ) + .withNamespace( "org.apache.maven" ).build(); + List projects = repoContent.getProjects( selector ); + assertEquals( 12, projects.size( ) ); + String[] expected = new String[]{ + "A", "B", "C", "archiva", "discovery", "maven-parent", "samplejar", "shared", "some-ejb", "test", + "testing", "update" + }; + Object[] actual = projects.stream( ).map( p -> p.getId( ) ).sorted( ).toArray( ); + assertArrayEquals( expected, actual); + } + + @Test + public void testGetVersionsWithIllegalSelector() { + ItemSelector selector = ArchivaItemSelector.builder( ) + .withNamespace( "org.apache.maven" ).build(); + try + { + List versions = repoContent.getVersions( selector ); + assertFalse( "IllegalArgumentException expected, when project id not set", true ); + } catch (IllegalArgumentException e) { + assertEquals( "Project id not set, while retrieving versions.", e.getMessage( ) ); + } + } + + @Test + public void testGetVersionsWithSelector() { + ItemSelector selector = ArchivaItemSelector.builder( ) + .withNamespace( "org.apache.maven" ) + .withProjectId( "samplejar" ).build(); + List versions = repoContent.getVersions( selector ); + assertNotNull( versions ); + assertEquals( 2, versions.size( ) ); + } + + + @Override + protected ItemSelector toItemSelector( String path ) throws LayoutException + { + return repoContent.toItemSelector( path ); + } + + @Override + protected String toPath( Artifact reference ) + { + return repoContent.toPath( reference ); + } + + @Override + protected String toPath( ItemSelector selector ) { + return repoContent.toPath( selector ); + } + + @Override + protected ManagedRepositoryContent getManaged( ) + { + return repoContent; + } + + @Override + protected RepositoryContent getContent( ) + { + return repoContent; + } + + private Path setupRepoCopy( String source, String target) throws IOException + { + Path defaultRepo = getRepositoryPath( source ); + Path newRepo = defaultRepo.getParent( ).resolve( target ); + FileUtils.copyDirectory( defaultRepo.toFile( ), newRepo.toFile( ) ); + + MavenManagedRepository repository = createRepository( "testRepo", "Unit Test Repo", newRepo ); + + FileType fileType = archivaConfiguration.getConfiguration().getRepositoryScanning().getFileTypes().get( 0 ); + fileType.addPattern( "**/*.xml" ); + assertEquals( FileTypes.ARTIFACTS, fileType.getId() ); + + fileTypes.afterConfigurationChange( null, "fileType", null ); + + repoContent = new ManagedDefaultRepositoryContent(repository, fileTypes, fileLockManager); + return newRepo; + + } + + + @Test + public void testGetArtifactStreamWithVersionSelector() { + ItemSelector selector = ArchivaItemSelector.builder( ) + .withNamespace( "javax.sql" ) + .withProjectId( "jdbc" ) + .withVersion( "2.0" ).build(); + try(Stream stream = repoContent.newArtifactStream( selector )) + { + assertNotNull( stream ); + List results = stream.collect( Collectors.toList( ) ); + checkArtifactListWithVersionSelector1( results ); + } + } + + @Test + public void testGetArtifactListWithVersionSelector() { + ItemSelector selector = ArchivaItemSelector.builder( ) + .withNamespace( "javax.sql" ) + .withProjectId( "jdbc" ) + .withVersion( "2.0" ).build(); + List results = repoContent.getArtifacts( selector ); + checkArtifactListWithVersionSelector1( results ); + } + + private void checkArtifactListWithVersionSelector1( List results ) + { + assertNotNull( results ); + assertEquals( 2, results.size( ) ); + Artifact mainArtifact = results.stream( ).filter( a -> a.getFileName( ).equals( "jdbc-2.0.jar" ) ).findFirst( ).get( ); + assertNotNull( mainArtifact ); + assertEquals( BaseArtifactTypes.MAIN, mainArtifact.getDataType( ) ); + Artifact metaArtifact = results.stream( ).filter( a -> a.getFileName( ).equals( "maven-metadata-repository.xml" ) ).findFirst( ).get( ); + assertNotNull( metaArtifact ); + assertEquals( MavenTypes.REPOSITORY_METADATA, metaArtifact.getDataType( ) ); + } + + @Test + public void testGetArtifactStreamWithVersionSelector2() { + ItemSelector selector = ArchivaItemSelector.builder( ) + .withNamespace( "org.apache.axis2" ) + .withProjectId( "axis2" ) + .withVersion( "1.3-SNAPSHOT" ).build(); + try(Stream stream = repoContent.newArtifactStream( selector )) + { + assertNotNull( stream ); + List results = stream.collect( Collectors.toList( ) ); + checkArtifactListWithVersionSelector2( results ); + } + } + + @Test + public void testGetArtifactListWithVersionSelector2() { + ItemSelector selector = ArchivaItemSelector.builder( ) + .withNamespace( "org.apache.axis2" ) + .withProjectId( "axis2" ) + .withVersion( "1.3-SNAPSHOT" ).build(); + List results = repoContent.getArtifacts( selector ); + checkArtifactListWithVersionSelector2( results ); + } + + private void checkArtifactListWithVersionSelector2( List results ) + { + assertNotNull( results ); + assertEquals( 39, results.size( ) ); + + Artifact artifact = results.stream( ).filter( a -> a.getFileName( ).equals( "axis2-1.3-20070725.210059-1.pom" ) ) + .findFirst( ).get( ); + + assertNotNull( artifact ); + assertEquals( "pom", artifact.getExtension( ) ); + assertEquals( BaseArtifactTypes.MAIN, artifact.getDataType( ) ); + assertEquals( "1.3-SNAPSHOT", artifact.getVersion( ).getId( ) ); + assertEquals( "1.3-20070725.210059-1", artifact.getArtifactVersion( ) ); + assertEquals( ".pom", artifact.getRemainder( ) ); + assertEquals( "axis2", artifact.getId( ) ); + assertEquals( "axis2", artifact.getVersion( ).getProject( ).getId( ) ); + assertEquals( "org.apache.axis2", artifact.getVersion( ).getProject( ).getNamespace( ).getId( ) ); + assertEquals( "", artifact.getClassifier( ) ); + assertEquals( "pom", artifact.getType( ) ); + + artifact = null; + artifact = results.stream( ).filter( a -> a.getFileName( ).equals( "axis2-1.3-20070725.210059-1.pom.md5" ) ) + .findFirst( ).get( ); + + assertNotNull( artifact ); + assertEquals( "md5", artifact.getExtension( ) ); + assertEquals( BaseArtifactTypes.RELATED, artifact.getDataType( ) ); + assertEquals( "1.3-SNAPSHOT", artifact.getVersion( ).getId( ) ); + assertEquals( "1.3-20070725.210059-1", artifact.getArtifactVersion( ) ); + assertEquals( ".pom.md5", artifact.getRemainder( ) ); + assertEquals( "axis2", artifact.getId( ) ); + assertEquals( "axis2", artifact.getVersion( ).getProject( ).getId( ) ); + assertEquals( "org.apache.axis2", artifact.getVersion( ).getProject( ).getNamespace( ).getId( ) ); + assertEquals( "", artifact.getClassifier( ) ); + assertEquals( "md5", artifact.getType( ) ); + + + artifact = null; + artifact = results.stream( ).filter( a -> a.getFileName( ).equals( "maven-metadata.xml" ) ) + .findFirst( ).get( ); + assertNotNull( artifact ); + assertEquals( BaseArtifactTypes.METADATA, artifact.getDataType( ) ); + assertEquals( "1.3-SNAPSHOT", artifact.getVersion( ).getId( ) ); + assertEquals( "xml", artifact.getExtension( ) ); + } + + @Test + public void testGetArtifactListWithArtifactSelector1() { + ItemSelector selector = ArchivaItemSelector.builder( ) + .withNamespace( "org.apache.axis2" ) + .withProjectId( "axis2" ) + .withVersion( "1.3-SNAPSHOT" ) + .withArtifactVersion( "1.3-20070731.113304-21" ) + .withExtension( "pom" ) + .build( ); + List results = repoContent.getArtifacts( selector ); + checkArtifactListWithArtifactSelector1( results ); + } + + @Test + public void testGetArtifactStreamWithArtifactSelector1() { + ItemSelector selector = ArchivaItemSelector.builder( ) + .withNamespace( "org.apache.axis2" ) + .withProjectId( "axis2" ) + .withVersion( "1.3-SNAPSHOT" ) + .withArtifactVersion( "1.3-20070731.113304-21" ) + .withExtension( "pom" ) + .build( ); + try(Stream results = repoContent.newArtifactStream( selector )) + { + checkArtifactListWithArtifactSelector1( results.collect( Collectors.toList()) ); + } + } + + private void checkArtifactListWithArtifactSelector1( List results ) + { + assertNotNull( results ); + assertEquals( 1, results.size( ) ); + Artifact artifact = results.get( 0 ); + assertEquals( "pom", artifact.getExtension( ) ); + assertEquals( BaseArtifactTypes.MAIN, artifact.getDataType( ) ); + } + + @Test + public void testGetArtifactListWithArtifactSelector2() { + ItemSelector selector = ArchivaItemSelector.builder( ) + .withNamespace( "org.apache.axis2" ) + .withProjectId( "axis2" ) + .withVersion( "1.3-SNAPSHOT" ) + .withArtifactVersion( "1.3-20070731.113304-21" ) + .withExtension( "pom" ) + .includeRelatedArtifacts() + .build( ); + List results = repoContent.getArtifacts( selector ); + + checkArtifactListWithArtifactSelector2( results ); + + } + + @Test + public void testGetArtifactStreamWithArtifactSelector2() { + ItemSelector selector = ArchivaItemSelector.builder( ) + .withNamespace( "org.apache.axis2" ) + .withProjectId( "axis2" ) + .withVersion( "1.3-SNAPSHOT" ) + .withArtifactVersion( "1.3-20070731.113304-21" ) + .withExtension( "pom" ) + .includeRelatedArtifacts() + .build( ); + try(Stream results = repoContent.newArtifactStream( selector )) + { + checkArtifactListWithArtifactSelector2( results.collect( Collectors.toList()) ); + } + } + + private void checkArtifactListWithArtifactSelector2( List results ) + { + assertNotNull( results ); + assertEquals( 3, results.size( ) ); + Artifact artifact = results.stream( ).filter( a -> a.getFileName( ).equalsIgnoreCase( "axis2-1.3-20070731.113304-21.pom" ) ) + .findFirst( ).get( ); + assertNotNull( artifact ); + assertEquals( "pom", artifact.getExtension( ) ); + assertEquals( BaseArtifactTypes.MAIN, artifact.getDataType( ) ); + + artifact = results.stream( ).filter( a -> a.getFileName( ).equalsIgnoreCase( "axis2-1.3-20070731.113304-21.pom.sha1" ) ) + .findFirst( ).get( ); + assertNotNull( artifact ); + assertEquals( "sha1", artifact.getExtension( ) ); + assertEquals( BaseArtifactTypes.RELATED, artifact.getDataType( ) ); + } + + + @Test + public void testArtifactListWithProjectSelector() { + ItemSelector selector = ArchivaItemSelector.builder( ) + .withNamespace( "org.apache.maven.shared" ) + .withProjectId( "maven-downloader" ) + .build( ); + List results = repoContent.getArtifacts( selector ); + checkArtifactListWithProjectSelector( results ); + + } + + @Test + public void testArtifactStreamWithProjectSelector() { + ItemSelector selector = ArchivaItemSelector.builder( ) + .withNamespace( "org.apache.maven.shared" ) + .withProjectId( "maven-downloader" ) + .build( ); + Stream results = repoContent.newArtifactStream( selector ); + checkArtifactListWithProjectSelector( results.collect( Collectors.toList()) ); + + } + + private void checkArtifactListWithProjectSelector( List results ) + { + assertNotNull( results ); + assertEquals( 27, results.size( ) ); + + Artifact artifact = results.stream( ).filter( a -> a.getFileName( ).equalsIgnoreCase( "maven-metadata.xml" ) ) + .findFirst( ).get( ); + assertNotNull( artifact ); + assertEquals( "xml", artifact.getExtension( ) ); + assertEquals( BaseArtifactTypes.METADATA, artifact.getDataType( ) ); + + artifact = results.stream( ).filter( a -> a.getFileName( ).equalsIgnoreCase( "maven-downloader-1.0-sources.jar" ) ) + .findFirst( ).get( ); + assertNotNull( artifact ); + assertEquals( BaseArtifactTypes.MAIN, artifact.getDataType( ) ); + assertEquals( "sources", artifact.getClassifier( ) ); + assertEquals( "java-source", artifact.getType( ) ); + + artifact = results.stream( ).filter( a -> a.getFileName( ).equalsIgnoreCase( "maven-downloader-1.0-sources.jar.sha1" ) ) + .findFirst( ).get( ); + assertNotNull( artifact ); + assertEquals( BaseArtifactTypes.RELATED, artifact.getDataType( ) ); + assertEquals( "sources", artifact.getClassifier( ) ); + assertEquals( "sha1", artifact.getType( ) ); + assertEquals( ".jar.sha1", artifact.getRemainder( ) ); + } + + @Test + public void testArtifactListWithNamespaceSelector() { + ItemSelector selector = ArchivaItemSelector.builder( ) + .withNamespace( "org.multilevel" ) + .build( ); + List results = repoContent.getArtifacts( selector ); + assertNotNull( results ); + assertEquals( 3, results.size( ) ); + assertTrue( results.get( 0 ).getFileName( ).startsWith( "testproj1" ) ); + } + + @Test + public void testArtifactListWithNamespaceSelectorRecursive() { + ItemSelector selector = ArchivaItemSelector.builder( ) + .withNamespace( "org.multilevel" ) + .recurse() + .build( ); + List results = repoContent.getArtifacts( selector ); + checkArtifactListWithNamespaceSelectorRecursive( results ); + } + + @Test + public void testArtifactStreamWithNamespaceSelectorRecursive() { + ItemSelector selector = ArchivaItemSelector.builder( ) + .withNamespace( "org.multilevel" ) + .recurse() + .build( ); + Stream results = repoContent.newArtifactStream( selector ); + checkArtifactListWithNamespaceSelectorRecursive( results.collect( Collectors.toList()) ); + } + + private void checkArtifactListWithNamespaceSelectorRecursive( List results ) + { + assertNotNull( results ); + assertEquals( 6, results.size( ) ); + + Artifact artifact = results.stream( ).filter( a -> a.getFileName( ).equalsIgnoreCase( "testproj2-1.0.pom" ) ) + .findFirst( ).get( ); + assertNotNull( artifact ); + assertEquals( 6, artifact.getAsset( ).getParent( ).getPath( ).split( "/" ).length ); + + artifact = results.stream( ).filter( a -> a.getFileName( ).equalsIgnoreCase( "testproj1-1.0.pom" ) ) + .findFirst( ).get( ); + assertNotNull( artifact ); + assertEquals( 5, artifact.getAsset( ).getParent( ).getPath( ).split( "/" ).length ); + } + + + @Test + public void testArtifactListWithArtifactSelector1() { + ItemSelector selector = ArchivaItemSelector.builder( ) + .withNamespace( "org.apache.maven" ) + .withProjectId( "test" ) + .withVersion( "1.0-SNAPSHOT" ) + .withArtifactId( "test" ) + .withArtifactVersion( "1.0-20050611.112233-1" ) + .build( ); + + List results = repoContent.getArtifacts( selector ); + + assertNotNull( results ); + assertEquals( 1, results.size( ) ); + + Artifact artifact = results.stream( ).filter( a -> a.getFileName( ).equalsIgnoreCase( "test-1.0-20050611.112233-1.jar" ) ) + .findFirst().get(); + assertNotNull( artifact ); + assertEquals( "", artifact.getClassifier( ) ); + } + + @Test + public void testArtifactListWithArtifactSelector2() { + ItemSelector selector = ArchivaItemSelector.builder( ) + .withNamespace( "org.apache.maven" ) + .withProjectId( "test" ) + .withVersion( "1.0-SNAPSHOT" ) + .withClassifier( "*" ) + .withArtifactId( "test" ) + .withArtifactVersion( "1.0-20050611.112233-1" ) + .build( ); + + List results = repoContent.getArtifacts( selector ); + + assertNotNull( results ); + assertEquals( 2, results.size( ) ); + + Artifact artifact = results.stream( ).filter( a -> a.getFileName( ).equalsIgnoreCase( "test-1.0-20050611.112233-1-javadoc.jar" ) ) + .findFirst().get(); + assertNotNull( artifact ); + assertEquals( "javadoc", artifact.getClassifier( ) ); + assertEquals( "javadoc", artifact.getType( ) ); + } + + @Test + public void testArtifactListWithArtifactSelector3() { + ItemSelector selector = ArchivaItemSelector.builder( ) + .withNamespace( "org.apache.maven" ) + .withProjectId( "test" ) + .withVersion( "1.0-SNAPSHOT" ) + .withClassifier( "*" ) + .withArtifactVersion( "1.0-20050611.112233-1" ) + .build( ); + + List results = repoContent.getArtifacts( selector ); + + assertNotNull( results ); + assertEquals( 3, results.size( ) ); + + Artifact artifact = results.stream( ).filter( a -> a.getFileName( ).equalsIgnoreCase( "test-1.0-20050611.112233-1-javadoc.jar" ) ) + .findFirst().get(); + assertNotNull( artifact ); + assertEquals( "javadoc", artifact.getClassifier( ) ); + assertEquals( "javadoc", artifact.getType( ) ); + + artifact = results.stream( ).filter( a -> a.getFileName( ).equalsIgnoreCase( "wrong-artifactId-1.0-20050611.112233-1.jar" ) ) + .findFirst().get(); + assertNotNull( artifact ); + assertEquals( "", artifact.getClassifier( ) ); + assertEquals( "wrong-artifactId", artifact.getId( ) ); + } + + @Test + public void testArtifactListWithArtifactSelector4() { + ItemSelector selector = ArchivaItemSelector.builder( ) + .withNamespace( "org.apache.maven" ) + .withProjectId( "test" ) + .withVersion( "1.0-SNAPSHOT" ) + .withClassifier( "" ) + .build( ); + + List results = repoContent.getArtifacts( selector ); + + assertNotNull( results ); + assertEquals( 5, results.size( ) ); + + Artifact artifact = results.stream( ).filter( a -> a.getFileName( ).equalsIgnoreCase( "test-1.0-20050611.112233-1-javadoc.jar" ) ) + .findFirst().get(); + assertNotNull( artifact ); + assertEquals( "javadoc", artifact.getClassifier( ) ); + assertEquals( "javadoc", artifact.getType( ) ); + + artifact = results.stream( ).filter( a -> a.getFileName( ).equalsIgnoreCase( "wrong-artifactId-1.0-20050611.112233-1.jar" ) ) + .findFirst().get(); + assertNotNull( artifact ); + assertEquals( "", artifact.getClassifier( ) ); + assertEquals( "wrong-artifactId", artifact.getId( ) ); + + artifact = results.stream( ).filter( a -> a.getFileName( ).equalsIgnoreCase( "wrong-artifactId-1.0-20050611.1122x-1.jar" ) ) + .findFirst().get(); + assertNotNull( artifact ); + assertEquals( "", artifact.getClassifier( ) ); + assertEquals( "wrong-artifactId", artifact.getId( ) ); + assertEquals( "", artifact.getArtifactVersion( ) ); + + artifact = results.stream( ).filter( a -> a.getFileName( ).equalsIgnoreCase( "test-1.0-20050611.1122x-1.jar" ) ) + .findFirst().get(); + assertNotNull( artifact ); + assertEquals( "", artifact.getClassifier( ) ); + assertEquals( "test", artifact.getId( ) ); + assertEquals( "1.0-20050611.1122x-1", artifact.getArtifactVersion( ) ); + + } + + @Test + public void testArtifactListWithArtifactSelectorWithClassifier() { + ItemSelector selector = ArchivaItemSelector.builder( ) + .withNamespace( "org.apache.maven" ) + .withProjectId( "test" ) + .withVersion( "1.0-SNAPSHOT" ) + .withArtifactId( "test" ) + .withClassifier( "javadoc" ) + .withArtifactVersion( "1.0-20050611.112233-1" ) + .build( ); + + List results = repoContent.getArtifacts( selector ); + + assertNotNull( results ); + assertEquals( 1, results.size( ) ); + + Artifact artifact = results.stream( ).filter( a -> a.getFileName( ).equalsIgnoreCase( "test-1.0-20050611.112233-1-javadoc.jar" ) ) + .findFirst().get(); + assertNotNull( artifact ); + assertEquals( "javadoc", artifact.getClassifier( ) ); + assertEquals( "javadoc", artifact.getType( ) ); + } + + @Test + public void testArtifactListWithArtifactSelectorWrongArtifact() { + ItemSelector selector = ArchivaItemSelector.builder( ) + .withNamespace( "org.apache.maven" ) + .withProjectId( "test" ) + .withVersion( "1.0-SNAPSHOT" ) + .withArtifactId( "wrong-artifactId" ) + .withArtifactVersion( "1.0-20050611.112233-1" ) + .build( ); + + List results = repoContent.getArtifacts( selector ); + + assertNotNull( results ); + assertEquals( 1, results.size( ) ); + + Artifact artifact = results.stream( ).filter( a -> a.getFileName( ).equalsIgnoreCase( "wrong-artifactId-1.0-20050611.112233-1.jar" ) ) + .findFirst().get(); + assertNotNull( artifact ); + } + + @Test + public void testArtifactListWithArtifactSelectorVersionPattern() { + ItemSelector selector = ArchivaItemSelector.builder( ) + .withNamespace( "org.apache.maven" ) + .withProjectId( "test" ) + .withVersion( "1.0-SNAPSHOT" ) + .withArtifactVersion( "1.0-*" ) + .build( ); + + List results = repoContent.getArtifacts( selector ); + + assertNotNull( results ); + assertEquals( 5, results.size( ) ); + + Artifact artifact = results.stream( ).filter( a -> a.getFileName( ).equalsIgnoreCase( "wrong-artifactId-1.0-20050611.112233-1.jar" ) ) + .findFirst().get(); + assertNotNull( artifact ); + } + + + @Test + public void testNewItemStreamWithNamespace1() { + ItemSelector selector = ArchivaItemSelector.builder( ) + .withNamespace( "org.apache.axis2" ) + .build(); + + Stream stream = repoContent.newItemStream( selector, false ); + List result = stream.collect( Collectors.toList( ) ); + assertEquals( 41, result.size( ) ); + ContentItem item = result.get( 39 ); + Version version = item.adapt( Version.class ); + assertNotNull( version ); + assertEquals( "1.3-SNAPSHOT", version.getId( ) ); + Project project = result.get( 40 ).adapt( Project.class ); + assertNotNull( project ); + assertEquals( "axis2", project.getId( ) ); + assertTrue( result.stream( ).anyMatch( a -> "axis2-1.3-20070725.210059-1.pom".equals( a.getAsset( ).getName( ) ) ) ); + } + + @Test + public void testNewItemStreamWithNamespace2() { + ItemSelector selector = ArchivaItemSelector.builder( ) + .withNamespace( "org.apache.maven" ) + .recurse() + .build(); + + Stream stream = repoContent.newItemStream( selector, false ); + List result = stream.collect( Collectors.toList( ) ); + assertEquals( 170, result.size( ) ); + assertEquals( 92, result.stream( ).filter( a -> a instanceof DataItem ).count( ) ); + } + + @Test + public void testGetArtifactFromContentItem() { + ItemSelector selector = ArchivaItemSelector.builder( ) + .withNamespace( "org.apache.maven" ).build(); + Namespace ns = repoContent.getNamespace( selector ); + List artifacts = repoContent.getArtifacts( ns ); + assertNotNull( artifacts ); + assertEquals( 39, artifacts.size( ) ); + List artifacts2 = repoContent.getArtifacts( (ContentItem)ns ); + assertArrayEquals( artifacts.toArray(), artifacts2.toArray() ); + + selector = ArchivaItemSelector.builder( ) + .withNamespace( "org.apache.maven.shared" ) + .withProjectId( "maven-downloader" ) + .build(); + Project project = repoContent.getProject( selector ); + artifacts = repoContent.getArtifacts( project ); + assertNotNull( artifacts ); + assertEquals( 27, artifacts.size( ) ); + artifacts2 = repoContent.getArtifacts( (ContentItem)project ); + assertArrayEquals( artifacts.toArray(), artifacts2.toArray() ); + + selector = ArchivaItemSelector.builder( ) + .withNamespace( "org.apache.maven.shared" ) + .withProjectId( "maven-downloader" ) + .withVersion( "1.1" ) + .build( ); + Version version = repoContent.getVersion( selector ); + artifacts = repoContent.getArtifacts( version ); + assertNotNull( artifacts ); + assertEquals( 12, artifacts.size( ) ); + artifacts2 = repoContent.getArtifacts( (ContentItem)version ); + assertArrayEquals( artifacts.toArray(), artifacts2.toArray() ); + + } + + @Test + public void testGetRelatedArtifactsFromArtifact() { + ItemSelector selector = ArchivaItemSelector.builder( ) + .withNamespace( "org.apache.maven.shared" ) + .withProjectId( "maven-downloader" ) + .withVersion( "1.1" ) + .withExtension( "jar" ) + .withArtifactId( "maven-downloader" ).build( ); + + Artifact artifact = repoContent.getArtifact( selector ); + assertNotNull( artifact ); + List artifacts = repoContent.getArtifacts( artifact ); + assertNotNull( artifacts ); + assertEquals( 2, artifacts.size( ) ); + + } + + @Test + public void testToItemFromPath() throws LayoutException + { + String path = "/org/apache/maven/shared"; + ContentItem item = repoContent.toItem( path ); + assertNotNull( item ); + assertTrue( item instanceof ArchivaContentItem ); + + path = "/org/apache/maven/shared/maven-downloader"; + item = repoContent.toItem( path ); + assertNotNull( item ); + assertTrue( item instanceof ArchivaContentItem ); + + path = "/org/apache/maven/shared/maven-downloader/1.1"; + item = repoContent.toItem( path ); + assertNotNull( item ); + assertTrue( item instanceof ArchivaContentItem ); + + path = "/org/apache/maven/shared/maven-downloader/1.1/maven-downloader-1.1.jar"; + item = repoContent.toItem( path ); + assertNotNull( item ); + assertTrue( item instanceof DataItem ); + + } + + @Test + public void testToItemFromAssetPath() throws LayoutException + { + StorageAsset path = repoContent.getRepository().getAsset("/org/apache/maven/shared"); + ContentItem item = repoContent.toItem( path ); + assertNotNull( item ); + assertTrue( item instanceof ArchivaContentItem ); + + path = repoContent.getRepository( ).getAsset( "/org/apache/maven/shared/maven-downloader" ); + item = repoContent.toItem( path ); + assertNotNull( item ); + assertTrue( item instanceof ArchivaContentItem ); + + path = repoContent.getRepository( ).getAsset( "/org/apache/maven/shared/maven-downloader/1.1" ); + item = repoContent.toItem( path ); + assertNotNull( item ); + assertTrue( item instanceof ArchivaContentItem ); + + path = repoContent.getRepository( ).getAsset( "/org/apache/maven/shared/maven-downloader/1.1/maven-downloader-1.1.jar" ); + item = repoContent.toItem( path ); + assertNotNull( item ); + assertTrue( item instanceof DataItem ); + + } + + @Test + public void testHasContent() throws LayoutException + { + ItemSelector selector = ArchivaItemSelector.builder( ) + .withNamespace( "org.apache.maven.shared" ) + .withProjectId( "maven-downloader" ) + .withVersion( "1.1" ) + .withArtifactId( "maven-downloader" ) + .withExtension( "jar" ) + .build(); + + assertTrue( repoContent.hasContent( selector ) ); + + selector = ArchivaItemSelector.builder( ) + .withNamespace( "org.apache.maven.shared" ) + .withProjectId( "maven-downloader" ) + .withVersion( "1.1" ) + .withArtifactId( "maven-downloader" ) + .withExtension( "zip" ) + .build(); + + assertFalse( repoContent.hasContent( selector ) ); + + } + + @Test + public void testGetItemWithNamespaceSelector() { + ItemSelector selector = ArchivaItemSelector.builder( ) + .withNamespace( "org.apache.maven" ) + .build( ); + ContentItem item = repoContent.getItem( selector ); + assertNotNull( item ); + assertTrue( item instanceof Namespace ); + } + + @Test + public void testGetItemWithProjectSelector() { + ItemSelector selector = ArchivaItemSelector.builder( ) + .withNamespace( "org.apache.maven" ) + .withProjectId( "shared" ) + .build( ); + ContentItem item = repoContent.getItem( selector ); + assertNotNull( item ); + assertTrue( item instanceof Project ); + } + + @Test + public void testGetItemWithVersionSelector() { + ItemSelector selector = ArchivaItemSelector.builder( ) + .withNamespace( "org.apache.maven" ) + .withProjectId( "samplejar" ) + .withVersion("2.0") + .build( ); + ContentItem item = repoContent.getItem( selector ); + assertNotNull( item ); + assertTrue( item instanceof Version ); + } + + @Test + public void testGetItemWithArtifactSelector() { + ItemSelector selector = ArchivaItemSelector.builder( ) + .withNamespace( "org.apache.maven" ) + .withProjectId( "samplejar" ) + .withVersion("2.0") + .withArtifactId( "samplejar" ) + .build( ); + ContentItem item = repoContent.getItem( selector ); + assertNotNull( item ); + assertTrue( item instanceof Artifact ); + } + + @Test + public void testGetNamespaceFromPath() throws LayoutException + { + StorageAsset path = repoContent.getRepository( ).getAsset( "/org/apache/axis2" ); + Namespace ns = repoContent.getNamespaceFromPath( path ); + assertNotNull( ns ); + assertEquals( "org.apache.axis2", ns.getId( ) ); + + } + + @Test + public void testArtifactListWithArtifactSelectorAndRelated() { + ItemSelector selector = ArchivaItemSelector.builder( ) + .withNamespace( "org.apache.maven" ) + .withProjectId( "samplejar" ) + .withVersion( "1.0" ) + .withArtifactVersion( "1.0" ) + .withArtifactId( "samplejar" ) + .withExtension( "jar" ) + .includeRelatedArtifacts() + .build( ); + + List results = repoContent.getArtifacts( selector ); + + assertNotNull( results ); + assertEquals( 3, results.size( ) ); + + Artifact artifact = results.stream( ).filter( a -> a.getFileName( ).equalsIgnoreCase( "samplejar-1.0.jar" ) ) + .findFirst().get(); + assertNotNull( artifact ); + assertEquals( BaseArtifactTypes.MAIN, artifact.getDataType( ) ); + + artifact = results.stream( ).filter( a -> a.getFileName( ).equalsIgnoreCase( "samplejar-1.0.jar.md5" ) ) + .findFirst().get(); + assertNotNull( artifact ); + assertEquals( BaseArtifactTypes.RELATED, artifact.getDataType( ) ); + assertEquals( "md5", artifact.getExtension( ) ); + + artifact = results.stream( ).filter( a -> a.getFileName( ).equalsIgnoreCase( "samplejar-1.0.jar.sha1" ) ) + .findFirst().get(); + assertNotNull( artifact ); + assertEquals( BaseArtifactTypes.RELATED, artifact.getDataType( ) ); + assertEquals( "sha1", artifact.getExtension( ) ); + + } + + private Path copyRepository(String repoName) throws IOException, URISyntaxException + { + Path tempDir = Files.createTempDirectory( "archiva-repocontent" ); + Path repoSource = Paths.get( Thread.currentThread( ).getContextClassLoader( ).getResource( "repositories/" + repoName ).toURI( ) ); + assertTrue( Files.exists( repoSource ) ); + FileUtils.copyDirectory( repoSource.toFile( ), tempDir.toFile() ); + return tempDir; + } + + private ManagedRepository createManagedRepoWithContent(String sourceRepoName) throws IOException, URISyntaxException + { + Path repoDir = copyRepository( sourceRepoName ); + MavenManagedRepository repo = createRepository( sourceRepoName, sourceRepoName, repoDir ); + ManagedDefaultRepositoryContent deleteRepoContent = new ManagedDefaultRepositoryContent( repo, fileTypes, fileLockManager ); + deleteRepoContent.setMavenContentHelper( contentHelper ); + return repo; + } + + @Test + public void deleteNamespaceItem() throws IOException, URISyntaxException, ItemNotFoundException + { + ManagedRepository repo = createManagedRepoWithContent( "delete-repository" ); + ManagedRepositoryContent myRepoContent = repo.getContent( ); + Path repoRoot = repo.getRoot().getFilePath( ); + assertTrue( Files.exists(repoRoot.resolve( "org/apache/maven" )) ); + ArchivaItemSelector selector = ArchivaItemSelector.builder( ) + .withNamespace( "org.apache.maven" ).build(); + ContentItem item = myRepoContent.getItem( selector ); + assertTrue( item instanceof Namespace ); + myRepoContent.deleteItem( item ); + assertFalse( Files.exists(repoRoot.resolve( "org/apache/maven" )) ); + assertTrue( Files.exists(repoRoot.resolve( "org/apache" )) ); + + // Sub namespaces are deleted too + assertTrue( Files.exists(repoRoot.resolve( "org/apache/test/samplejar" )) ); + assertTrue( Files.exists(repoRoot.resolve( "org/apache/test/sub/samplejar" )) ); + selector = ArchivaItemSelector.builder( ) + .withNamespace( "org.apache.test" ).build(); + item = myRepoContent.getItem( selector ); + assertTrue( item instanceof Namespace ); + myRepoContent.deleteItem( item ); + assertFalse( Files.exists(repoRoot.resolve( "org/apache/test/samplejar" )) ); + assertFalse( Files.exists(repoRoot.resolve( "org/apache/test/sub/samplejar" )) ); + } + + @Test + public void deleteProjectItem() throws IOException, URISyntaxException, ItemNotFoundException + { + ManagedRepository repo = createManagedRepoWithContent( "delete-repository" ); + ManagedRepositoryContent myRepoContent = repo.getContent( ); + Path repoRoot = repo.getRoot().getFilePath( ); + assertTrue( Files.exists(repoRoot.resolve( "org/apache/maven/A" )) ); + ArchivaItemSelector selector = ArchivaItemSelector.builder( ) + .withNamespace( "org.apache.maven" ) + .withProjectId( "A" ).build(); + ContentItem item = myRepoContent.getItem( selector ); + assertTrue( item instanceof Project ); + myRepoContent.deleteItem( item ); + assertTrue( Files.exists(repoRoot.resolve( "org/apache/maven" )) ); + assertTrue( Files.exists( repoRoot.resolve( "org/apache/maven/samplejar/1.0" ) ) ); + assertTrue( Files.exists( repoRoot.resolve( "org/apache/maven/samplejar/2.0" ) ) ); + assertFalse( Files.exists(repoRoot.resolve( "org/apache/maven/A" )) ); + + assertTrue( Files.exists(repoRoot.resolve( "org/apache/test/samplejar" )) ); + assertTrue( Files.exists(repoRoot.resolve( "org/apache/test/sub/samplejar" )) ); + selector = ArchivaItemSelector.builder( ) + .withNamespace( "org.apache.test" ) + .withProjectId( "samplejar" ).build(); + item = myRepoContent.getItem( selector ); + assertTrue( item instanceof Project ); + myRepoContent.deleteItem( item ); + assertFalse( Files.exists(repoRoot.resolve( "org/apache/test/samplejar" )) ); + assertTrue( Files.exists(repoRoot.resolve( "org/apache/test/sub/samplejar" )) ); + } + + @Test + public void deleteVersionItem() throws IOException, URISyntaxException, ItemNotFoundException + { + ManagedRepository repo = createManagedRepoWithContent( "delete-repository" ); + ManagedRepositoryContent myRepoContent = repo.getContent( ); + Path repoRoot = repo.getRoot().getFilePath( ); + assertTrue( Files.exists(repoRoot.resolve( "org/apache/maven/A/1.0" )) ); + ArchivaItemSelector selector = ArchivaItemSelector.builder( ) + .withNamespace( "org.apache.maven" ) + .withProjectId( "A" ) + .withVersion( "1.0" ).build(); + ContentItem item = myRepoContent.getItem( selector ); + assertTrue( item instanceof Version ); + myRepoContent.deleteItem( item ); + assertTrue( Files.exists(repoRoot.resolve( "org/apache/maven/A" )) ); + assertTrue( Files.exists( repoRoot.resolve( "org/apache/maven/samplejar/1.0" ) ) ); + assertTrue( Files.exists( repoRoot.resolve( "org/apache/maven/samplejar/2.0" ) ) ); + assertFalse( Files.exists(repoRoot.resolve( "org/apache/maven/A/1.0" )) ); + + assertTrue( Files.exists(repoRoot.resolve( "org/apache/test/samplejar" )) ); + assertTrue( Files.exists(repoRoot.resolve( "org/apache/test/sub/samplejar" )) ); + selector = ArchivaItemSelector.builder( ) + .withNamespace( "org.apache.test" ) + .withProjectId( "samplejar" ) + .withVersion( "2.0" ).build(); + item = myRepoContent.getItem( selector ); + assertTrue( item instanceof Version ); + myRepoContent.deleteItem( item ); + assertFalse( Files.exists(repoRoot.resolve( "org/apache/test/samplejar/2.0" )) ); + assertTrue( Files.exists(repoRoot.resolve( "org/apache/test/samplejar/1.0" )) ); + assertTrue( Files.exists(repoRoot.resolve( "org/apache/test/sub/samplejar/1.0" )) ); + assertTrue( Files.exists(repoRoot.resolve( "org/apache/test/sub/samplejar/2.0" )) ); + } + + @Test + public void deleteArtifactItem() throws IOException, URISyntaxException, ItemNotFoundException + { + ManagedRepository repo = createManagedRepoWithContent( "delete-repository" ); + ManagedRepositoryContent myRepoContent = repo.getContent( ); + Path repoRoot = repo.getRoot().getFilePath( ); + assertTrue( Files.exists(repoRoot.resolve( "org/apache/maven/A/1.0/A-1.0.pom" )) ); + assertTrue( Files.exists(repoRoot.resolve( "org/apache/maven/A/1.0/A-1.0.war" )) ); + ArchivaItemSelector selector = ArchivaItemSelector.builder( ) + .withNamespace( "org.apache.maven" ) + .withProjectId( "A" ) + .withVersion( "1.0" ) + .withArtifactId( "A" ) + .withArtifactVersion( "1.0" ) + .withExtension( "pom" ) + .build(); + ContentItem item = myRepoContent.getItem( selector ); + assertTrue( item instanceof Artifact ); + myRepoContent.deleteItem( item ); + assertTrue( Files.exists( repoRoot.resolve( "org/apache/maven/samplejar/1.0" ) ) ); + assertTrue( Files.exists( repoRoot.resolve( "org/apache/maven/samplejar/2.0" ) ) ); + assertFalse( Files.exists(repoRoot.resolve( "org/apache/maven/A/1.0/A-1.0.pom" )) ); + assertTrue( Files.exists(repoRoot.resolve( "org/apache/maven/A/1.0/A-1.0.war" )) ); + + + assertTrue( Files.exists(repoRoot.resolve( "org/apache/test/samplejar/1.0/samplejar-1.0.jar" )) ); + assertTrue( Files.exists(repoRoot.resolve( "org/apache/test/samplejar/1.0/samplejar-1.0.jar.md5" )) ); + assertTrue( Files.exists(repoRoot.resolve( "org/apache/test/samplejar/1.0/samplejar-1.0.jar.sha1" )) ); + assertTrue( Files.exists(repoRoot.resolve( "org/apache/test/samplejar/1.0/samplejar-1.0.pom" )) ); + assertTrue( Files.exists(repoRoot.resolve( "org/apache/test/samplejar/1.0/samplejar-1.0-source.jar" )) ); + selector = ArchivaItemSelector.builder( ) + .withNamespace( "org.apache.test" ) + .withProjectId( "samplejar" ) + .withVersion( "1.0" ) + .withArtifactId( "samplejar" ) + .withArtifactVersion( "1.0" ) + .withExtension( "jar" ) + .build(); + item = myRepoContent.getItem( selector ); + assertTrue( item instanceof Artifact ); + myRepoContent.deleteItem( item ); + assertFalse( Files.exists(repoRoot.resolve( "org/apache/test/samplejar/1.0/samplejar-1.0.jar" )) ); + assertTrue( Files.exists(repoRoot.resolve( "org/apache/test/samplejar/1.0/samplejar-1.0.jar.md5" )) ); + assertTrue( Files.exists(repoRoot.resolve( "org/apache/test/samplejar/1.0/samplejar-1.0.jar.sha1" )) ); + assertTrue( Files.exists(repoRoot.resolve( "org/apache/test/samplejar/1.0/samplejar-1.0.pom" )) ); + assertTrue( Files.exists(repoRoot.resolve( "org/apache/test/samplejar/1.0/samplejar-1.0-source.jar" )) ); + assertTrue( Files.exists(repoRoot.resolve( "org/apache/test/samplejar/2.0" )) ); + assertTrue( Files.exists(repoRoot.resolve( "org/apache/test/sub/samplejar/1.0" )) ); + assertTrue( Files.exists(repoRoot.resolve( "org/apache/test/sub/samplejar/2.0" )) ); + + selector = ArchivaItemSelector.builder( ) + .withNamespace( "org.apache.test" ) + .withProjectId( "samplejar" ) + .withVersion( "1.0" ) + .withArtifactId( "samplejar" ) + .withArtifactVersion( "1.0" ) + .withClassifier( "source" ) + .withExtension( "jar" ) + .build(); + item = myRepoContent.getItem( selector ); + assertTrue( item instanceof Artifact ); + myRepoContent.deleteItem( item ); + assertFalse( Files.exists(repoRoot.resolve( "org/apache/test/samplejar/1.0/samplejar-1.0.jar" )) ); + assertTrue( Files.exists(repoRoot.resolve( "org/apache/test/samplejar/1.0/samplejar-1.0.jar.md5" )) ); + assertTrue( Files.exists(repoRoot.resolve( "org/apache/test/samplejar/1.0/samplejar-1.0.jar.sha1" )) ); + assertTrue( Files.exists(repoRoot.resolve( "org/apache/test/samplejar/1.0/samplejar-1.0.pom" )) ); + assertFalse( Files.exists(repoRoot.resolve( "org/apache/test/samplejar/1.0/samplejar-1.0-source.jar" )) ); + assertTrue( Files.exists(repoRoot.resolve( "org/apache/test/samplejar/1.0/samplejar-1.0-source.jar.sha1" )) ); + assertTrue( Files.exists(repoRoot.resolve( "org/apache/test/samplejar/2.0" )) ); + assertTrue( Files.exists(repoRoot.resolve( "org/apache/test/sub/samplejar/1.0" )) ); + assertTrue( Files.exists(repoRoot.resolve( "org/apache/test/sub/samplejar/2.0" )) ); + + selector = ArchivaItemSelector.builder( ) + .withNamespace( "org.apache.test" ) + .withProjectId( "samplejar" ) + .withVersion( "1.0" ) + .withArtifactId( "samplejar" ) + .withArtifactVersion( "1.0" ) + .withExtension( "jar.md5" ) + .build(); + item = myRepoContent.getItem( selector ); + assertTrue( item instanceof Artifact ); + myRepoContent.deleteItem( item ); + assertFalse( Files.exists(repoRoot.resolve( "org/apache/test/samplejar/1.0/samplejar-1.0.jar" )) ); + assertFalse( Files.exists(repoRoot.resolve( "org/apache/test/samplejar/1.0/samplejar-1.0.jar.md5" )) ); + assertTrue( Files.exists(repoRoot.resolve( "org/apache/test/samplejar/1.0/samplejar-1.0.jar.sha1" )) ); + assertTrue( Files.exists(repoRoot.resolve( "org/apache/test/samplejar/1.0/samplejar-1.0.pom" )) ); + assertFalse( Files.exists(repoRoot.resolve( "org/apache/test/samplejar/1.0/samplejar-1.0-source.jar" )) ); + assertTrue( Files.exists(repoRoot.resolve( "org/apache/test/samplejar/1.0/samplejar-1.0-source.jar.sha1" )) ); + assertTrue( Files.exists(repoRoot.resolve( "org/apache/test/samplejar/2.0" )) ); + assertTrue( Files.exists(repoRoot.resolve( "org/apache/test/sub/samplejar/1.0" )) ); + assertTrue( Files.exists(repoRoot.resolve( "org/apache/test/sub/samplejar/2.0" )) ); + + + } + + @Test + public void deleteItemNotFound() throws IOException, URISyntaxException, ItemNotFoundException + { + ManagedRepository repo = createManagedRepoWithContent( "delete-repository" ); + ManagedRepositoryContent myRepoContent = repo.getContent( ); + Path repoRoot = repo.getRoot().getFilePath( ); + + ArchivaItemSelector selector = ArchivaItemSelector.builder( ) + .withNamespace( "org.apache.test2" ) + .build( ); + + ContentItem item = myRepoContent.getItem( selector ); + assertTrue( item instanceof Namespace ); + try + { + myRepoContent.deleteItem( item ); + assertTrue( "ItemNotFoundException expected for non existing namespace", false ); + } catch ( ItemNotFoundException e) { + } + + selector = ArchivaItemSelector.builder( ) + .withNamespace( "org.apache.test" ) + .withProjectId( "samplejar2" ) + .build( ); + item = myRepoContent.getItem( selector ); + assertTrue( item instanceof Project ); + try + { + myRepoContent.deleteItem( item ); + assertTrue( "ItemNotFoundException expected for non existing project", false ); + } catch ( ItemNotFoundException e) { + } + + selector = ArchivaItemSelector.builder( ) + .withNamespace( "org.apache.test" ) + .withProjectId( "samplejar" ) + .withVersion("1.1") + .build( ); + item = myRepoContent.getItem( selector ); + assertTrue( item instanceof Version ); + try + { + myRepoContent.deleteItem( item ); + assertTrue( "ItemNotFoundException expected for non existing version", false ); + } catch ( ItemNotFoundException e) { + } + + selector = ArchivaItemSelector.builder( ) + .withNamespace( "org.apache.test" ) + .withProjectId( "samplejar" ) + .withVersion("1.0") + .withArtifactId( "samplejar" ) + .withArtifactVersion( "1.0" ) + .withExtension( "jax" ) + .build( ); + item = myRepoContent.getItem( selector ); + assertTrue( item instanceof Artifact ); + try + { + myRepoContent.deleteItem( item ); + assertTrue( "ItemNotFoundException expected for non existing artifact", false ); + } catch ( ItemNotFoundException e) { + } + + } + + + @Test + public void testAddArtifact() throws IOException, URISyntaxException, LayoutException + { + ManagedRepository repo = createManagedRepoWithContent( "delete-repository" ); + ManagedRepositoryContent myRepoContent = repo.getContent( ); + BaseRepositoryContentLayout layout = myRepoContent.getLayout( BaseRepositoryContentLayout.class ); + Path repoRoot = repo.getRoot().getFilePath( ); + + Path tmpFile = Files.createTempFile( "archiva-mvn-repotest", "jar" ); + try( OutputStream outputStream = Files.newOutputStream( tmpFile )) + { + for ( int i = 0; i < 255; i++ ) + { + outputStream.write( "test.test.test\n".getBytes( Charset.forName( "UTF-8" ) ) ); + } + } + + Path file = repoRoot.resolve( "org/apache/maven/samplejar/2.0/samplejar-2.0.jar" ); + FileTime lmt = Files.getLastModifiedTime( file ); + ArchivaItemSelector selector = ArchivaItemSelector.builder( ) + .withNamespace( "org.apache.maven" ) + .withProjectId( "samplejar" ) + .withVersion( "2.0" ) + .withArtifactId( "samplejar" ) + .withArtifactVersion( "2.0" ) + .withExtension( "jar" ) + .build( ); + Artifact artifact = layout.getArtifact( selector ); + layout.addArtifact( tmpFile, artifact ); + FileTime lmtAfter = Files.getLastModifiedTime( file ); + assertNotEquals( lmtAfter, lmt ); + Reader ln = Files.newBufferedReader( file, Charset.forName( "UTF-8" ) ); + char[] content = new char[50]; + ln.read( content ); + assertTrue( new String( content ).startsWith( "test.test.test" ) ); + + tmpFile = Files.createTempFile( "archiva-mvn-repotest", "jar" ); + try( OutputStream outputStream = Files.newOutputStream( tmpFile )) + { + for ( int i = 0; i < 255; i++ ) + { + outputStream.write( "test.test.test\n".getBytes( Charset.forName( "UTF-8" ) ) ); + } + } + file = repoRoot.resolve( "org/apache/maven/samplejar/2.0/samplejar-2.0.test" ); + assertFalse( Files.exists( file ) ); + assertTrue( Files.exists( tmpFile ) ); + selector = ArchivaItemSelector.builder( ) + .withNamespace( "org.apache.maven" ) + .withProjectId( "samplejar" ) + .withVersion( "2.0" ) + .withArtifactId( "samplejar" ) + .withArtifactVersion( "2.0" ) + .withExtension( "test" ) + .build( ); + artifact = layout.getArtifact( selector ); + layout.addArtifact( tmpFile, artifact ); + ln = Files.newBufferedReader( file, Charset.forName( "UTF-8" ) ); + ln.read( content ); + assertTrue( new String( content ).startsWith( "test.test.test" ) ); + } + + @Test + public void getExistingMetadataItem() { + // org/apache/maven/some-ejb/1.0 + ArchivaItemSelector versionSelector = ArchivaItemSelector.builder( ) + .withNamespace( "org.apache.maven" ) + .withProjectId( "some-ejb" ) + .withVersion( "1.0" ).build( ); + Version version = repoContent.getVersion( versionSelector ); + DataItem metaData = repoContent.getMetadataItem( version ); + assertTrue( metaData.exists( ) ); + assertEquals( "/org/apache/maven/some-ejb/1.0/maven-metadata.xml", metaData.getAsset( ).getPath( ) ); + } + + @Test + public void getNonExistingMetadataItem() { + // org/apache/maven/some-ejb/1.0 + ArchivaItemSelector versionSelector = ArchivaItemSelector.builder( ) + .withNamespace( "javax.sql" ) + .withProjectId( "jdbc" ) + .withVersion( "2.0" ).build( ); + Version version = repoContent.getVersion( versionSelector ); + DataItem metaData = repoContent.getMetadataItem( version ); + assertFalse( metaData.exists( ) ); + assertEquals( "/javax/sql/jdbc/2.0/maven-metadata.xml", metaData.getAsset( ).getPath( ) ); + } + +} diff --git a/archiva-modules/archiva-maven/archiva-maven-repository/src/test/java/org/apache/archiva/maven/repository/content/MavenContentHelperTest.java b/archiva-modules/archiva-maven/archiva-maven-repository/src/test/java/org/apache/archiva/maven/repository/content/MavenContentHelperTest.java new file mode 100644 index 000000000..5d4c66f04 --- /dev/null +++ b/archiva-modules/archiva-maven/archiva-maven-repository/src/test/java/org/apache/archiva/maven/repository/content/MavenContentHelperTest.java @@ -0,0 +1,209 @@ +package org.apache.archiva.maven.repository.content; + +/* + * 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.filelock.DefaultFileLockManager; +import org.apache.archiva.maven.metadata.MavenMetadataReader; +import org.apache.archiva.repository.content.ItemSelector; +import org.apache.archiva.repository.content.base.ArchivaItemSelector; +import org.apache.archiva.repository.storage.StorageAsset; +import org.apache.archiva.repository.storage.fs.FilesystemStorage; +import org.junit.jupiter.api.AfterAll; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.Test; + +import java.io.IOException; +import java.net.URISyntaxException; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNotNull; + +/** + * @author Martin Stockhammer + */ +class MavenContentHelperTest +{ + + private static FilesystemStorage storage; + private static Path tempDir; + + @BeforeAll + static void setUp() throws IOException + { + tempDir = Files.createTempDirectory( "archivamaventest" ); + storage = new FilesystemStorage( tempDir, new DefaultFileLockManager() ); + } + + @AfterAll + static void tearDown() { + try + { + Files.deleteIfExists( tempDir ); + } + catch ( IOException e ) + { + System.err.println( "Could not delete " + tempDir ); + } + } + + @Test + void getNamespaceFromNamespacePath( ) + { + StorageAsset asset = storage.getAsset( "org/apache/archiva" ); + String ns = MavenContentHelper.getNamespaceFromNamespacePath( asset ); + assertNotNull( ns ); + assertEquals( "org.apache.archiva", ns ); + + asset = storage.getRoot(); + ns = MavenContentHelper.getNamespaceFromNamespacePath( asset ); + assertNotNull( ns ); + assertEquals( "", ns ); + } + + @Test + void getArtifactVersion( ) throws IOException, URISyntaxException + { + MavenContentHelper mavenContentHelper = new MavenContentHelper( ); + MavenMetadataReader reader = new MavenMetadataReader( ); + mavenContentHelper.setMetadataReader( reader ); + Path testRepoPath = Paths.get( Thread.currentThread( ).getContextClassLoader( ).getResource( "repositories/metadata-repository" ).toURI() ); + FilesystemStorage storage = new FilesystemStorage( testRepoPath, new DefaultFileLockManager( ) ); + assertArtifactVersion( mavenContentHelper, "1.0-alpha-11-SNAPSHOT", storage.getAsset( "org/apache/archiva/metadata/tests/snap_shots_1/1.0-alpha-11-SNAPSHOT" ) + , "1.0-alpha-11-SNAPSHOT", "1.0-alpha-11-SNAPSHOT"); + + assertArtifactVersion( mavenContentHelper, "1.0-alpha-11-20070316.175232-11", storage.getAsset( "org/apache/archiva/metadata/tests/snap_shots_a/1.0-alpha-11-SNAPSHOT" ) + , "", "1.0-alpha-11-SNAPSHOT"); + + assertArtifactVersion( mavenContentHelper, "2.2-20070316.153953-10", storage.getAsset( "org/apache/archiva/metadata/tests/snap_shots_b/2.2-SNAPSHOT" ) + , "", "2.2-SNAPSHOT"); + + } + + private void assertArtifactVersion(MavenContentHelper mavenContentHelper, String expectedVersion, StorageAsset dir, String selectorArtifactVersion, String selectorVersion) { + ItemSelector selector = ArchivaItemSelector.builder( ) + .withVersion( selectorVersion ) + .withArtifactVersion( selectorArtifactVersion ) + .build( ); + assertEquals( expectedVersion, mavenContentHelper.getArtifactVersion( dir, selector ) ); + } + + @Test + void getLatestArtifactSnapshotVersion( ) throws URISyntaxException, IOException + { + MavenContentHelper mavenContentHelper = new MavenContentHelper( ); + MavenMetadataReader reader = new MavenMetadataReader( ); + mavenContentHelper.setMetadataReader( reader ); + Path testRepoPath = Paths.get( Thread.currentThread( ).getContextClassLoader( ).getResource( "repositories/default-repository" ).toURI() ); + FilesystemStorage storage = new FilesystemStorage( testRepoPath, new DefaultFileLockManager( ) ); + // Directory without metadata file + assertEquals( "2.1-20090808.085535-2", mavenContentHelper.getLatestArtifactSnapshotVersion( storage.getAsset( "org/apache/archiva/sample-parent/2.1-SNAPSHOT" ), "2.1-SNAPSHOT" ) ); + // Directory with metadata file + assertEquals( "1.3-20070802.113139-29", mavenContentHelper.getLatestArtifactSnapshotVersion( storage.getAsset( "org/apache/axis2/axis2/1.3-SNAPSHOT" ), "1.3-SNAPSHOT" ) ); + } + + @Test + void getArtifactFileName( ) + { + assertFileName( "test-1.0.jar", "test", "", "1.0", "jar" ); + assertFileName( "test-1.1-client.jar", "test", "client", "1.1", "jar" ); + assertFileName( "te445st-2.1-sources.jar", "te445st", "sources", "2.1", "jar" ); + assertFileName( "abcde-8888.994894.48484-10.jar", "abcde", "", "8888.994894.48484-10", "jar" ); + assertFileName( "testarchive-5.0.war", "testarchive", "", "5.0", "war" ); + } + + private void assertFileName(String expectedFilename, String artifactId, String classifier, String version, String extension) { + assertEquals( expectedFilename, MavenContentHelper.getArtifactFileName( artifactId, version, classifier, extension ) ); + } + + @Test + void getClassifier( ) + { + assertClassifier( "sources", "","java-source" ); + assertClassifier( "tests", "", "test-jar" ); + assertClassifier( "client", "","ejb-client" ); + assertClassifier( "javadoc", "","javadoc" ); + assertClassifier( "", "","test" ); + assertClassifier( "test1", "test1","java-source" ); + assertClassifier( "test2", "test2", "test-jar" ); + assertClassifier( "test3", "test3","ejb-client" ); + assertClassifier( "test4", "test4","javadoc" ); + assertClassifier( "test5", "test5","test" ); + } + private void assertClassifier(String expectedClassifier, String classifier, String type) { + ItemSelector selector = ArchivaItemSelector.builder( ) + .withClassifier( classifier ) + .withType( type ).build(); + assertEquals( expectedClassifier, MavenContentHelper.getClassifier( selector ) ); + } + + @Test + void getClassifierFromType( ) + { + assertClassifier( "sources", "java-source" ); + assertClassifier( "tests", "test-jar" ); + assertClassifier( "client", "ejb-client" ); + assertClassifier( "javadoc", "javadoc" ); + assertClassifier( "", "test" ); + } + + private void assertClassifier(String expectedClassifier, String type) { + assertEquals( expectedClassifier, MavenContentHelper.getClassifierFromType( type ) ); + } + + @Test + void getTypeFromClassifierAndExtension( ) + { + assertType( "javadoc", "javadoc", "jar" ); + assertType( "war", "", "war" ); + assertType( "ear", "", "ear" ); + assertType( "rar", "", "rar" ); + assertType( "java-source", "sources", "jar" ); + assertType( "ejb-client", "client", "jar" ); + assertType( "pom", "", "pom" ); + assertType( "test-jar", "tests", "jar" ); + + } + + private void assertType(String expectedType, String classifier, String extension) { + assertEquals( expectedType, MavenContentHelper.getTypeFromClassifierAndExtension( classifier, extension ) ); + } + + + + @Test + void getArtifactExtension( ) + { + assertExtension( "test", "", "test" ); + assertExtension( "jar", "javadoc", "" ); + assertExtension( "war", "war", "" ); + assertExtension( "ear", "ear", "" ); + assertExtension( "rar", "rar", "" ); + assertExtension( "jar", "", "" ); + } + + private void assertExtension( String expectedExtension, String type, String extension ) + { + ItemSelector selector = ArchivaItemSelector.builder( ) + .withType( type ).withExtension( extension ).build(); + assertEquals( expectedExtension, MavenContentHelper.getArtifactExtension( selector ) ); + } +} \ No newline at end of file diff --git a/archiva-modules/archiva-maven/archiva-maven-repository/src/test/java/org/apache/archiva/maven/repository/content/MavenRepositoryRequestInfoTest.java b/archiva-modules/archiva-maven/archiva-maven-repository/src/test/java/org/apache/archiva/maven/repository/content/MavenRepositoryRequestInfoTest.java new file mode 100644 index 000000000..1cfdc4709 --- /dev/null +++ b/archiva-modules/archiva-maven/archiva-maven-repository/src/test/java/org/apache/archiva/maven/repository/content/MavenRepositoryRequestInfoTest.java @@ -0,0 +1,587 @@ +package org.apache.archiva.maven.repository.content; + +/* + * 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.filelock.FileLockManager; +import org.apache.archiva.common.utils.FileUtils; +import org.apache.archiva.configuration.ArchivaConfiguration; +import org.apache.archiva.configuration.FileType; +import org.apache.archiva.configuration.FileTypes; +import org.apache.archiva.maven.repository.MavenManagedRepository; +import org.apache.archiva.maven.repository.metadata.storage.ArtifactMappingProvider; +import org.apache.archiva.metadata.repository.storage.RepositoryPathTranslator; +import org.apache.archiva.repository.ManagedRepositoryContent; +import org.apache.archiva.repository.RepositoryContentProvider; +import org.apache.archiva.repository.content.ItemSelector; +import org.apache.archiva.repository.content.LayoutException; +import org.apache.archiva.test.utils.ArchivaSpringJUnit4ClassRunner; +import org.apache.commons.lang3.StringUtils; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.context.ApplicationContext; +import org.springframework.test.context.ContextConfiguration; + +import javax.inject.Inject; +import javax.inject.Named; +import java.io.IOException; +import java.net.URISyntaxException; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.util.List; + +import static org.junit.Assert.*; + +/** + * RepositoryRequestTest + */ +@RunWith( ArchivaSpringJUnit4ClassRunner.class ) +@ContextConfiguration( { "classpath*:/META-INF/spring-context.xml", + "classpath:/spring-context-repo-request-test.xml" } ) +public class MavenRepositoryRequestInfoTest +{ + + @Inject + protected ApplicationContext applicationContext; + + @Inject + FileTypes fileTypes; + + @Inject + @Named( "archivaConfiguration#repo-request-test" ) + private ArchivaConfiguration archivaConfiguration; + + @Inject + List artifactMappingProviders; + + @Inject + @Named( "repositoryPathTranslator#maven2" ) + RepositoryPathTranslator pathTranslator; + + @Inject + FileLockManager fileLockManager; + + @Inject + MavenContentHelper mavenContentHelper; + + private MavenRepositoryRequestInfo repoRequest; + + + protected MavenManagedRepository createRepository( String id, String name, Path location ) throws IOException { + MavenManagedRepository repo = MavenManagedRepository.newLocalInstance( id, name, location.getParent().toAbsolutePath()); + repo.setLocation( location.toAbsolutePath().toUri() ); + return repo; + } + + private Path getRepositoryPath(String repoName) { + try + { + return Paths.get( Thread.currentThread( ).getContextClassLoader( ).getResource( "repositories/" + repoName ).toURI( ) ); + } + catch ( URISyntaxException e ) + { + throw new RuntimeException( "Could not resolve repository path " + e.getMessage( ), e ); + } + } + + @Before + public void setUp() + throws Exception + { + + Path repoDir = getRepositoryPath( "default-repository" ); + MavenManagedRepository repository = createRepository( "testRepo", "Unit Test Repo", repoDir ); + + FileType fileType = archivaConfiguration.getConfiguration().getRepositoryScanning().getFileTypes().get( 0 ); + fileType.addPattern( "**/*.xml" ); + assertEquals( FileTypes.ARTIFACTS, fileType.getId() ); + + fileTypes.afterConfigurationChange( null, "fileType", null ); + + ManagedDefaultRepositoryContent repoContent = new ManagedDefaultRepositoryContent(repository, fileTypes, fileLockManager); + //repoContent = (ManagedRepositoryContent) lookup( ManagedRepositoryContent.class, "default" ); + repository.setContent(repoContent); + repoContent.setMavenContentHelper( mavenContentHelper ); + repoContent.setArtifactMappingProviders( artifactMappingProviders ); + repoContent.setPathTranslator( pathTranslator ); + + repoRequest = new MavenRepositoryRequestInfo(repository); + } + + @Test + public void testInvalidRequestEmptyPath() + { + assertInvalidRequest( "" ); + } + + @Test + public void testInvalidRequestSlashOnly() + { + assertInvalidRequest( "//" ); + } + + @Test + public void testInvalidRequestNoArtifactId() + { + assertInvalidRequest( "groupId/jars/-1.0.jar" ); + } + + + @Test + public void testInvalidRequestTooShort() + { + assertInvalidRequest( "org.apache.maven.test/artifactId-2.0.jar" ); + } + + @Test + public void testInvalidDefaultRequestBadLocation() + { + assertInvalidRequest( "invalid/invalid/1.0-20050611.123456-1/invalid-1.0-20050611.123456-1.jar" ); + } + + @Test( expected = LayoutException.class ) + public void testValidLegacyGanymed() + throws Exception + { + assertValid( "ch.ethz.ganymed/jars/ganymed-ssh2-build210.jar", "ch.ethz.ganymed", "ganymed-ssh2", "build210", + "build210", null, "jar" ); + } + + @Test + public void testValidDefaultGanymed() + throws Exception + { + assertValid( "ch/ethz/ganymed/ganymed-ssh2/build210/ganymed-ssh2-build210.jar", "ch.ethz.ganymed", + "ganymed-ssh2", "build210", "build210", null, "jar" ); + } + + @Test( expected = LayoutException.class ) + public void testValidLegacyJavaxComm() + throws Exception + { + assertValid( "javax/jars/comm-3.0-u1.jar", "javax", "comm", "3.0-u1", "3.0-u1", null, "jar" ); + } + + @Test + public void testValidDefaultJavaxComm() + throws Exception + { + assertValid( "javax/comm/3.0-u1/comm-3.0-u1.jar", "javax", "comm", "3.0-u1", "3.0-u1", null, "jar" ); + } + + @Test( expected = LayoutException.class ) + public void testValidLegacyJavaxPersistence() + throws Exception + { + assertValid( "javax.persistence/jars/ejb-3.0-public_review.jar", "javax.persistence", "ejb", + "3.0-public_review", "3.0-public_review", null, "jar" ); + } + + @Test + public void testValidDefaultJavaxPersistence() + throws Exception + { + assertValid( "javax/persistence/ejb/3.0-public_review/ejb-3.0-public_review.jar", "javax.persistence", "ejb", + "3.0-public_review", "3.0-public_review",null, "jar" ); + } + + @Test( expected = LayoutException.class ) + public void testValidLegacyMavenTestPlugin() + throws Exception + { + assertValid( "maven/jars/maven-test-plugin-1.8.2.jar", "maven", "maven-test-plugin", "1.8.2", "1.8.2",null, "jar" ); + } + + @Test + public void testValidDefaultMavenTestPlugin() + throws Exception + { + assertValid( "maven/maven-test-plugin/1.8.2/maven-test-plugin-1.8.2.pom", "maven", "maven-test-plugin", "1.8.2", "1.8.2", + null, "pom" ); + } + + @Test( expected = LayoutException.class ) + public void testValidLegacyCommonsLangJavadoc() + throws Exception + { + assertValid( "commons-lang/javadoc.jars/commons-lang-2.1-javadoc.jar", "commons-lang", "commons-lang", "2.1", "2.1", + "javadoc", "javadoc" ); + } + + @Test + public void testValidDefaultCommonsLangJavadoc() + throws Exception + { + assertValid( "commons-lang/commons-lang/2.1/commons-lang-2.1-javadoc.jar", "commons-lang", "commons-lang", + "2.1", "2.1","javadoc", "javadoc" ); + } + + @Test( expected = LayoutException.class ) + public void testValidLegacyDerbyPom() + throws Exception + { + assertValid( "org.apache.derby/poms/derby-10.2.2.0.pom", "org.apache.derby", "derby", "10.2.2.0", "10.2.2.0",null, "pom" ); + // Starting slash should not prevent detection. + assertValid( "/org.apache.derby/poms/derby-10.2.2.0.pom", "org.apache.derby", "derby", "10.2.2.0", "10.2.2.0",null, + "pom" ); + } + + @Test + public void testValidDefaultDerbyPom() + throws Exception + { + assertValid( "org/apache/derby/derby/10.2.2.0/derby-10.2.2.0.pom", "org.apache.derby", "derby", "10.2.2.0", "10.2.2.0", + null, "pom" ); + } + + @Test( expected = LayoutException.class ) + public void testValidLegacyGeronimoEjbSpec() + throws Exception + { + assertValid( "org.apache.geronimo.specs/jars/geronimo-ejb_2.1_spec-1.0.1.jar", "org.apache.geronimo.specs", + "geronimo-ejb_2.1_spec", "1.0.1", "1.0.1",null, "jar" ); + } + + @Test + public void testValidDefaultGeronimoEjbSpec() + throws Exception + { + assertValid( "org/apache/geronimo/specs/geronimo-ejb_2.1_spec/1.0.1/geronimo-ejb_2.1_spec-1.0.1.jar", + "org.apache.geronimo.specs", "geronimo-ejb_2.1_spec", "1.0.1", "1.0.1",null, "jar" ); + } + + @Test( expected = LayoutException.class ) + public void testValidLegacyLdapSnapshot() + throws Exception + { + assertValid( "directory-clients/poms/ldap-clients-0.9.1-SNAPSHOT.pom", "directory-clients", "ldap-clients", + "0.9.1-SNAPSHOT", "0.9.1-SNAPSHOT",null, "pom" ); + } + + @Test + public void testValidDefaultLdapSnapshot() + throws Exception + { + assertValid( "directory-clients/ldap-clients/0.9.1-SNAPSHOT/ldap-clients-0.9.1-SNAPSHOT.pom", + "directory-clients", "ldap-clients", "0.9.1-SNAPSHOT", "0.9.1-SNAPSHOT",null, "pom" ); + } + + @Test( expected = LayoutException.class ) + public void testValidLegacyTestArchSnapshot() + throws Exception + { + assertValid( "test.maven-arch/poms/test-arch-2.0.3-SNAPSHOT.pom", "test.maven-arch", "test-arch", + "2.0.3-SNAPSHOT", "2.0.3-SNAPSHOT",null, "pom" ); + } + + @Test + public void testValidDefaultTestArchSnapshot() + throws Exception + { + assertValid( "test/maven-arch/test-arch/2.0.3-SNAPSHOT/test-arch-2.0.3-SNAPSHOT.pom", "test.maven-arch", + "test-arch", "2.0.3-SNAPSHOT", "2.0.3-SNAPSHOT",null, "pom" ); + } + + @Test( expected = LayoutException.class ) + public void testValidLegacyOddDottedArtifactId() + throws Exception + { + assertValid( "com.company.department/poms/com.company.department.project-0.2.pom", "com.company.department", + "com.company.department.project", "0.2", "0.2",null, "pom" ); + } + + @Test + public void testValidDefaultOddDottedArtifactId() + throws Exception + { + assertValid( "com/company/department/com.company.department.project/0.2/com.company.department.project-0.2.pom", + "com.company.department", "com.company.department.project", "0.2", "0.2",null, "pom" ); + } + + @Test( expected = LayoutException.class ) + public void testValidLegacyTimestampedSnapshot() + throws Exception + { + assertValid( "org.apache.archiva.test/jars/redonkulous-3.1-beta-1-20050831.101112-42.jar", + "org.apache.archiva.test", "redonkulous", "3.1-beta-1-20050831.101112-42", "3.1-beta-1-20050831.101112-42", null, "jar" ); + } + + @Test + public void testValidDefaultTimestampedSnapshot() + throws Exception + { + assertValid( + "org/apache/archiva/test/redonkulous/3.1-beta-1-SNAPSHOT/redonkulous-3.1-beta-1-20050831.101112-42.jar", + "org.apache.archiva.test", "redonkulous", "3.1-beta-1-SNAPSHOT", "3.1-beta-1-20050831.101112-42", null, "jar" ); + } + + @Test + public void testIsSupportFile() + { + assertTrue( repoRequest.isSupportFile( "org/apache/derby/derby/10.2.2.0/derby-10.2.2.0-bin.tar.gz.sha1" ) ); + assertTrue( repoRequest.isSupportFile( "org/apache/derby/derby/10.2.2.0/derby-10.2.2.0-bin.tar.gz.md5" ) ); + assertTrue( repoRequest.isSupportFile( "org/apache/derby/derby/10.2.2.0/derby-10.2.2.0-bin.tar.gz.asc" ) ); + assertTrue( repoRequest.isSupportFile( "org/apache/derby/derby/10.2.2.0/derby-10.2.2.0-bin.tar.gz.pgp" ) ); + assertTrue( repoRequest.isSupportFile( "org/apache/derby/derby/10.2.2.0/maven-metadata.xml.sha1" ) ); + assertTrue( repoRequest.isSupportFile( "org/apache/derby/derby/10.2.2.0/maven-metadata.xml.md5" ) ); + + assertFalse( repoRequest.isSupportFile( "test.maven-arch/poms/test-arch-2.0.3-SNAPSHOT.pom" ) ); + assertFalse( + repoRequest.isSupportFile( "test/maven-arch/test-arch/2.0.3-SNAPSHOT/test-arch-2.0.3-SNAPSHOT.jar" ) ); + assertFalse( repoRequest.isSupportFile( "org/apache/archiva/archiva-api/1.0/archiva-api-1.0.xml.zip" ) ); + assertFalse( repoRequest.isSupportFile( "org/apache/derby/derby/10.2.2.0/derby-10.2.2.0-bin.tar.gz" ) ); + assertFalse( repoRequest.isSupportFile( "org/apache/derby/derby/10.2.2.0/maven-metadata.xml" ) ); + assertFalse( repoRequest.isSupportFile( "org/apache/derby/derby/maven-metadata.xml" ) ); + } + + @Test + public void testIsMetadata() + { + assertTrue( repoRequest.isMetadata( "org/apache/derby/derby/10.2.2.0/maven-metadata.xml" ) ); + assertTrue( repoRequest.isMetadata( "org/apache/derby/derby/maven-metadata.xml" ) ); + + assertFalse( repoRequest.isMetadata( "test.maven-arch/poms/test-arch-2.0.3-SNAPSHOT.pom" ) ); + assertFalse( + repoRequest.isMetadata( "test/maven-arch/test-arch/2.0.3-SNAPSHOT/test-arch-2.0.3-SNAPSHOT.jar" ) ); + assertFalse( repoRequest.isMetadata( "org/apache/archiva/archiva-api/1.0/archiva-api-1.0.xml.zip" ) ); + assertFalse( repoRequest.isMetadata( "org/apache/derby/derby/10.2.2.0/derby-10.2.2.0-bin.tar.gz" ) ); + assertFalse( repoRequest.isMetadata( "org/apache/derby/derby/10.2.2.0/derby-10.2.2.0-bin.tar.gz.pgp" ) ); + assertFalse( repoRequest.isMetadata( "org/apache/derby/derby/10.2.2.0/maven-metadata.xml.sha1" ) ); + } + + @Test + public void testIsMetadataSupportFile() + { + assertFalse( repoRequest.isMetadataSupportFile( "org/apache/derby/derby/10.2.2.0/maven-metadata.xml" ) ); + assertFalse( repoRequest.isMetadataSupportFile( "org/apache/derby/derby/maven-metadata.xml" ) ); + assertTrue( repoRequest.isMetadataSupportFile( "org/apache/derby/derby/maven-metadata.xml.sha1" ) ); + assertTrue( repoRequest.isMetadataSupportFile( "org/apache/derby/derby/maven-metadata.xml.md5" ) ); + + assertFalse( repoRequest.isMetadataSupportFile( "test.maven-arch/poms/test-arch-2.0.3-SNAPSHOT.pom" ) ); + assertFalse( repoRequest.isMetadataSupportFile( + "test/maven-arch/test-arch/2.0.3-SNAPSHOT/test-arch-2.0.3-SNAPSHOT.jar" ) ); + assertFalse( + repoRequest.isMetadataSupportFile( "org/apache/archiva/archiva-api/1.0/archiva-api-1.0.xml.zip" ) ); + assertFalse( repoRequest.isMetadataSupportFile( "org/apache/derby/derby/10.2.2.0/derby-10.2.2.0-bin.tar.gz" ) ); + assertFalse( + repoRequest.isMetadataSupportFile( "org/apache/derby/derby/10.2.2.0/derby-10.2.2.0-bin.tar.gz.pgp" ) ); + assertTrue( repoRequest.isMetadataSupportFile( "org/apache/derby/derby/10.2.2.0/maven-metadata.xml.sha1" ) ); + assertTrue( repoRequest.isMetadataSupportFile( "org/apache/derby/derby/10.2.2.0/maven-metadata.xml.md5" ) ); + } + + @Test + public void testIsDefault() + { + assertNotEquals( "default", repoRequest.getLayout( "test.maven-arch/poms/test-arch-2.0.3-SNAPSHOT.pom" ) ); + assertNotEquals("default", repoRequest.getLayout( "directory-clients/poms/ldap-clients-0.9.1-SNAPSHOT.pom" ) ); + assertNotEquals("default", repoRequest.getLayout( "commons-lang/jars/commons-lang-2.1-javadoc.jar" ) ); + + assertEquals("default", repoRequest.getLayout( "test/maven-arch/test-arch/2.0.3-SNAPSHOT/test-arch-2.0.3-SNAPSHOT.jar" ) ); + assertEquals("default", repoRequest.getLayout( "org/apache/archiva/archiva-api/1.0/archiva-api-1.0.xml.zip" ) ); + assertEquals("default", repoRequest.getLayout( "org/apache/derby/derby/10.2.2.0/derby-10.2.2.0-bin.tar.gz" ) ); + assertEquals("default", repoRequest.getLayout( "org/apache/derby/derby/10.2.2.0/derby-10.2.2.0-bin.tar.gz.pgp" ) ); + assertEquals("default", repoRequest.getLayout( "org/apache/derby/derby/10.2.2.0/maven-metadata.xml.sha1" ) ); + assertEquals("default", repoRequest.getLayout( "eclipse/jdtcore/maven-metadata.xml" ) ); + assertEquals("default", repoRequest.getLayout( "eclipse/jdtcore/maven-metadata.xml.sha1" ) ); + assertEquals("default", repoRequest.getLayout( "eclipse/jdtcore/maven-metadata.xml.md5" ) ); + + assertNotEquals("default", repoRequest.getLayout( null ) ); + assertNotEquals("default", repoRequest.getLayout( "" ) ); + assertNotEquals("default", repoRequest.getLayout( "foo" ) ); + assertNotEquals("default", repoRequest.getLayout( "some.short/path" ) ); + } + + @Test + public void testIsLegacy() + { + assertEquals("legacy", repoRequest.getLayout( "test.maven-arch/poms/test-arch-2.0.3-SNAPSHOT.pom" ) ); + assertEquals("legacy", repoRequest.getLayout( "directory-clients/poms/ldap-clients-0.9.1-SNAPSHOT.pom" ) ); + assertEquals("legacy", repoRequest.getLayout( "commons-lang/jars/commons-lang-2.1-javadoc.jar" ) ); + + assertNotEquals("legacy", repoRequest.getLayout( "test/maven-arch/test-arch/2.0.3-SNAPSHOT/test-arch-2.0.3-SNAPSHOT.jar" ) ); + assertNotEquals("legacy", repoRequest.getLayout( "org/apache/archiva/archiva-api/1.0/archiva-api-1.0.xml.zip" ) ); + assertNotEquals("legacy", repoRequest.getLayout( "org/apache/derby/derby/10.2.2.0/derby-10.2.2.0-bin.tar.gz" ) ); + assertNotEquals("legacy", repoRequest.getLayout( "org/apache/derby/derby/10.2.2.0/derby-10.2.2.0-bin.tar.gz.pgp" ) ); + assertNotEquals("legacy", repoRequest.getLayout( "org/apache/derby/derby/10.2.2.0/maven-metadata.xml.sha1" ) ); + + assertNotEquals("legacy", repoRequest.getLayout( null ) ); + assertNotEquals("legacy", repoRequest.getLayout( "" ) ); + assertNotEquals("legacy", repoRequest.getLayout( "some.short/path" ) ); + } + + private ManagedRepositoryContent createManagedRepo( String layout ) + throws Exception + { + Path repoRoot = Paths.get( FileUtils.getBasedir() + "/target/test-repo" ); + return createManagedRepositoryContent( "test-internal", "Internal Test Repo", repoRoot, layout ); + } + + /** + * [MRM-481] Artifact requests with a .xml.zip extension fail with a 404 Error + */ + @Test + public void testToNativePathArtifactDefaultToDefaultDualExtension() + throws Exception + { + ManagedRepositoryContent repository = createManagedRepo( "default" ); + + // Test (artifact) default to default - dual extension + assertEquals( "/org/project/example-presentation/3.2/example-presentation-3.2.xml.zip", + repoRequest.toNativePath( "org/project/example-presentation/3.2/example-presentation-3.2.xml.zip") ); + } + + + @Test + public void testToNativePathMetadataDefaultToDefault() + throws Exception + { + ManagedRepositoryContent repository = createManagedRepo( "default" ); + + // Test (metadata) default to default + assertEquals( "/org/apache/derby/derby/10.2.2.0/maven-metadata.xml.sha1", + repoRequest.toNativePath( "org/apache/derby/derby/10.2.2.0/maven-metadata.xml.sha1") ); + } + + + @Test + public void testNativePathBadRequestTooShort() + throws Exception + { + ManagedRepositoryContent repository = createManagedRepo( "default" ); + + // Test bad request path (too short) + try + { + repoRequest.toNativePath( "org.apache.derby/license.txt"); + fail( "Should have thrown an exception about a too short path." ); + } + catch ( LayoutException e ) + { + // expected path. + } + } + + @Test + public void testNativePathBadRequestBlank() + throws Exception + { + ManagedRepositoryContent repository = createManagedRepo( "default" ); + + // Test bad request path (too short) + try + { + repoRequest.toNativePath( ""); + fail( "Should have thrown an exception about an blank request." ); + } + catch ( LayoutException e ) + { + // expected path. + } + } + + @Test + public void testNativePathBadRequestNull() + throws Exception + { + ManagedRepositoryContent repository = createManagedRepo( "default" ); + + // Test bad request path (too short) + try + { + repoRequest.toNativePath( null); + fail( "Should have thrown an exception about an null request." ); + } + catch ( LayoutException e ) + { + // expected path. + } + } + + @Test + public void testNativePathBadRequestUnknownType() + throws Exception + { + ManagedRepositoryContent repository = createManagedRepo( "default" ); + + // Test bad request path (too short) + try + { + repoRequest.toNativePath( "org/apache/derby/derby/10.2.2.0/license.txt"); + fail( "Should have thrown an exception about an invalid type." ); + } + catch ( LayoutException e ) + { + // expected path. + } + } + + + private void assertValid( String path, String groupId, String artifactId, String version, String artifactVersion, String classifier, + String type ) + throws Exception + { + String expectedId = + "ArtifactReference - " + groupId + ":" + artifactId + ":" + version + ":" + ( classifier != null ? + classifier + ":" : "" ) + type; + + ItemSelector reference = repoRequest.toItemSelector( path ); + + assertNotNull( expectedId + " - Should not be null.", reference ); + + assertEquals( expectedId + " - Group ID", groupId, reference.getNamespace() ); + assertEquals( expectedId + " - Artifact ID", artifactId, reference.getArtifactId() ); + assertEquals( expectedId + " - Artifact Version", artifactVersion, reference.getArtifactVersion( ) ); + if ( StringUtils.isNotBlank( classifier ) ) + { + assertEquals( expectedId + " - Classifier", classifier, reference.getClassifier() ); + } + assertEquals( expectedId + " - Version ID", version, reference.getVersion() ); + assertEquals( expectedId + " - Type", type, reference.getType() ); + } + + private void assertInvalidRequest( String path ) + { + try + { + repoRequest.toItemSelector( path ); + fail( "Expected a LayoutException on an invalid path [" + path + "]" ); + } + catch ( LayoutException e ) + { + /* expected path */ + } + } + + protected ManagedRepositoryContent createManagedRepositoryContent( String id, String name, Path location, + String layout ) + throws Exception + { + MavenManagedRepository repo = MavenManagedRepository.newLocalInstance( id, name, archivaConfiguration.getRepositoryBaseDir()); + repo.setLocation( location.toAbsolutePath().toUri() ); + repo.setLayout( layout ); + + RepositoryContentProvider provider = applicationContext.getBean( "repositoryContentProvider#maven", RepositoryContentProvider.class ); + + ManagedRepositoryContent repoContent = + provider.createManagedContent( repo ); + + return repoContent; + } + +} diff --git a/archiva-modules/archiva-maven/archiva-maven-repository/src/test/java/org/apache/archiva/maven/repository/content/RemoteDefaultRepositoryContentTest.java b/archiva-modules/archiva-maven/archiva-maven-repository/src/test/java/org/apache/archiva/maven/repository/content/RemoteDefaultRepositoryContentTest.java new file mode 100644 index 000000000..70aeb1f40 --- /dev/null +++ b/archiva-modules/archiva-maven/archiva-maven-repository/src/test/java/org/apache/archiva/maven/repository/content/RemoteDefaultRepositoryContentTest.java @@ -0,0 +1,102 @@ +package org.apache.archiva.maven.repository.content; + +/* + * 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.maven.repository.metadata.storage.ArtifactMappingProvider; +import org.apache.archiva.metadata.repository.storage.RepositoryPathTranslator; +import org.apache.archiva.repository.ManagedRepositoryContent; +import org.apache.archiva.repository.RemoteRepository; +import org.apache.archiva.repository.RepositoryContent; +import org.apache.archiva.repository.content.Artifact; +import org.apache.archiva.repository.content.ItemSelector; +import org.apache.archiva.repository.content.LayoutException; +import org.junit.Before; + +import javax.inject.Inject; +import javax.inject.Named; +import java.util.List; + +/** + * RemoteDefaultRepositoryContentTest + */ +public class RemoteDefaultRepositoryContentTest + extends AbstractRepositoryContentTest +{ + + @Inject + private List artifactMappingProviders; + + @Inject + @Named( "repositoryPathTranslator#maven2" ) + RepositoryPathTranslator pathTranslator; + + private RemoteDefaultRepositoryContent repoContent; + + @Before + public void setUp() + throws Exception + { + RemoteRepository repository = + createRemoteRepository( "testRemoteRepo", "Unit Test Remote Repo", "http://repo1.maven.org/maven2/" ); + + repoContent = new RemoteDefaultRepositoryContent(); + repoContent.setArtifactMappingProviders( artifactMappingProviders ); + repoContent.setPathTranslator( pathTranslator ); + + //repoContent = (RemoteRepositoryContent) lookup( RemoteRepositoryContent.class, "default" ); + repoContent.setRepository( repository ); + } + + @Override + protected Artifact createArtifact( String groupId, String artifactId, String version, String classifier, String type ) throws LayoutException + { + return null; + } + + + @Override + protected String toPath( Artifact reference ) throws LayoutException + { + ItemSelector selector = toItemSelector( reference.getAsset( ).getPath( ) ); + return repoContent.toPath( selector ); + } + + @Override + protected ItemSelector toItemSelector( String path ) throws LayoutException + { + return repoContent.toItemSelector( path ); + } + + @Override + protected ManagedRepositoryContent getManaged( ) + { + return null; + } + + @Override + protected RepositoryContent getContent( ) + { + return repoContent; + } + + @Override + protected String toPath( ItemSelector selector ) { + return repoContent.toPath( selector ); + } +} diff --git a/archiva-modules/archiva-maven/archiva-maven-repository/src/test/java/org/apache/archiva/maven/repository/dependency/tree/DependencyTreeBuilderTestMaven3.java b/archiva-modules/archiva-maven/archiva-maven-repository/src/test/java/org/apache/archiva/maven/repository/dependency/tree/DependencyTreeBuilderTestMaven3.java new file mode 100644 index 000000000..c78ae5f9d --- /dev/null +++ b/archiva-modules/archiva-maven/archiva-maven-repository/src/test/java/org/apache/archiva/maven/repository/dependency/tree/DependencyTreeBuilderTestMaven3.java @@ -0,0 +1,143 @@ +package org.apache.archiva.maven.repository.dependency.tree; + +/* + * 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.configuration.ArchivaConfiguration; +import org.apache.archiva.configuration.Configuration; +import org.apache.archiva.configuration.ManagedRepositoryConfiguration; +import org.apache.archiva.maven.model.Artifact; +import org.apache.archiva.maven.model.TreeEntry; +import org.apache.archiva.repository.RepositoryRegistry; +import org.apache.archiva.test.utils.ArchivaSpringJUnit4ClassRunner; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.test.context.ContextConfiguration; + +import javax.inject.Inject; +import javax.inject.Named; +import java.nio.file.Paths; +import java.util.Collections; +import java.util.List; + +import static org.assertj.core.api.Assertions.assertThat; + +@RunWith( ArchivaSpringJUnit4ClassRunner.class ) +@ContextConfiguration( { "classpath*:/META-INF/spring-context.xml", "classpath:/spring-context.xml" } ) +public class DependencyTreeBuilderTestMaven3 + extends TestCase +{ + @Inject + @Named( "dependencyTreeBuilder#maven3" ) + private Maven3DependencyTreeBuilder builder; + + private static final String TEST_REPO_ID = "test"; + + private static final String TEST_VERSION = "1.2.1"; + + private static final String TEST_ARTIFACT_ID = "archiva-common"; + + private static final String TEST_GROUP_ID = "org.apache.archiva"; + + + @Inject + @Named( "archivaConfiguration#test" ) + ArchivaConfiguration config; + + @Inject + RepositoryRegistry repositoryRegistry; + + @Before + @Override + public void setUp() + throws Exception + { + super.setUp(); + + Configuration configuration = new Configuration(); + ManagedRepositoryConfiguration repoConfig = new ManagedRepositoryConfiguration(); + repoConfig.setId( TEST_REPO_ID ); + repoConfig.setLocation(Paths.get("target/test-repository").toAbsolutePath().toString() ); + configuration.addManagedRepository( repoConfig ); + + config.getConfiguration().getProxyConnectors().clear(); + config.save( configuration ); + + repositoryRegistry.reload(); + + //artifactFactory = ((DefaultDependencyTreeBuilder)this.builder).getFactory(); + } + + + private Artifact createArtifact( String groupId, String artifactId, String version ) + { + return new Artifact( groupId, artifactId, version ); + } + + private String getId( Artifact artifact ) + { + return artifact.getGroupId() + ":" + artifact.getArtifactId() + ":" + artifact.getVersion(); + } + + @Test + public void testBuilderDependencies() + throws Exception + { + + List treeEntries = + builder.buildDependencyTree( Collections.singletonList( TEST_REPO_ID ), TEST_GROUP_ID, TEST_ARTIFACT_ID, + TEST_VERSION ); + + Artifact artifact = new Artifact( TEST_GROUP_ID, TEST_ARTIFACT_ID, TEST_VERSION, "", "" ); + artifact.setFileExtension("jar"); + assertThat( treeEntries ).isNotNull().isNotEmpty().contains(new TreeEntry(artifact) ); + + artifact = new Artifact( "commons-lang", "commons-lang", "2.2", "compile", "" ); + artifact.setFileExtension("jar"); + assertThat( treeEntries.get( 0 ).getChilds() ).isNotNull().isNotEmpty().contains( + new TreeEntry(artifact) ); + } + + + public static class TestTreeEntry + extends TreeEntry + { + Artifact a; + + public TestTreeEntry( Artifact a ) + { + this.a = a; + } + + @Override + public int hashCode() + { + return this.a.hashCode(); + } + + @Override + public boolean equals( Object o ) + { + Artifact artifact = ( (TreeEntry) o ).getArtifact(); + return artifact.equals( this.a ); + } + } + +} diff --git a/archiva-modules/archiva-maven/archiva-maven-repository/src/test/java/org/apache/archiva/maven/repository/merge/Maven2RepositoryMergerTest.java b/archiva-modules/archiva-maven/archiva-maven-repository/src/test/java/org/apache/archiva/maven/repository/merge/Maven2RepositoryMergerTest.java new file mode 100644 index 000000000..780d1b729 --- /dev/null +++ b/archiva-modules/archiva-maven/archiva-maven-repository/src/test/java/org/apache/archiva/maven/repository/merge/Maven2RepositoryMergerTest.java @@ -0,0 +1,213 @@ +package org.apache.archiva.maven.repository.merge; + +/* + * 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.configuration.ArchivaConfiguration; +import org.apache.archiva.configuration.Configuration; +import org.apache.archiva.configuration.ManagedRepositoryConfiguration; +import org.apache.archiva.configuration.RepositoryScanningConfiguration; +import org.apache.archiva.metadata.model.ArtifactMetadata; +import org.apache.archiva.metadata.repository.MetadataRepository; +import org.apache.archiva.metadata.repository.MetadataRepositoryException; +import org.apache.archiva.metadata.repository.RepositorySession; +import org.apache.archiva.metadata.repository.RepositorySessionFactory; +import org.apache.archiva.test.utils.ArchivaSpringJUnit4ClassRunner; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.MockitoAnnotations; +import org.springframework.test.context.ContextConfiguration; + +import javax.inject.Inject; +import javax.inject.Named; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.util.ArrayList; +import java.util.List; + +import static org.mockito.Mockito.*; + +@RunWith (ArchivaSpringJUnit4ClassRunner.class) +@ContextConfiguration (locations = { "classpath*:/META-INF/spring-context.xml", "classpath*:/spring-context-merge.xml" }) +public class Maven2RepositoryMergerTest + extends TestCase +{ + + private static final String TEST_REPO_ID = "test"; + + @Inject + private Maven2RepositoryMerger repositoryMerger; + + @Inject + @Named("archivaConfiguration#default") + ArchivaConfiguration configuration; + + private MetadataRepository metadataRepository; + + private static RepositorySessionFactory repositorySessionFactory; + + private static RepositorySession session; + + static + { + repositorySessionFactory = mock(RepositorySessionFactory.class); + session = mock( RepositorySession.class ); + + try + { + when( repositorySessionFactory.createSession( ) ).thenReturn( session ); + } + catch ( MetadataRepositoryException e ) + { + throw new RuntimeException( e ); + } + + } + + public static RepositorySessionFactory getRepositorySessionFactory() { + return repositorySessionFactory; + } + + + + @Before + @Override + public void setUp() + throws Exception + { + super.setUp(); + MockitoAnnotations.initMocks( this ); + metadataRepository = mock( MetadataRepository.class ); + repositoryMerger.setRepositorySessionFactory( repositorySessionFactory ); + + } + + private List getArtifacts() + { + List metadata = new ArrayList<>(); + ArtifactMetadata artifact1 = new ArtifactMetadata(); + artifact1.setNamespace( "com.example.test" ); + artifact1.setProject( "test-artifact" ); + artifact1.setVersion( "1.0-SNAPSHOT" ); + artifact1.setProjectVersion( "1.0-SNAPSHOT" ); + artifact1.setId( "test-artifact-1.0-20100308.230825-1.jar" ); + + metadata.add( artifact1 ); + return metadata; + } + + @Test + public void testMerge() + throws Exception + { + String targetRepoPath = "target/test-repository-target"; + Path mergedArtifact = Paths.get( targetRepoPath, + "com/example/test/test-artifact/1.0-SNAPSHOT/test-artifact-1.0-20100308.230825-1.jar" ); + + Path mavenMetadata = Paths.get( targetRepoPath, "com/example/test/test-artifact/maven-metadata.xml" ); + + Path pom = Paths.get( targetRepoPath, + "com/example/test/test-artifact/1.0-SNAPSHOT/test-artifact-1.0-20100308.230825-1.pom" ); + + for (Path testArtifact : new Path[] { mergedArtifact, mavenMetadata, pom }) { + Files.deleteIfExists(testArtifact); + } + + assertFalse( "Artifact file exists already", Files.exists(mergedArtifact) ); + assertFalse( "Metadata file exists already", Files.exists(mavenMetadata) ); + assertFalse( "Pom File exists already", Files.exists(pom) ); + Configuration c = new Configuration(); + ManagedRepositoryConfiguration testRepo = new ManagedRepositoryConfiguration(); + testRepo.setId( TEST_REPO_ID ); + testRepo.setLocation( "target/test-repository" ); + + RepositoryScanningConfiguration repoScanConfig = new RepositoryScanningConfiguration(); + List knownContentConsumers = new ArrayList<>(); + knownContentConsumers.add( "metadata-updater12" ); + repoScanConfig.setKnownContentConsumers( knownContentConsumers ); + c.setRepositoryScanning( repoScanConfig ); + + ManagedRepositoryConfiguration targetRepo = new ManagedRepositoryConfiguration(); + targetRepo.setId( "target-rep" ); + targetRepo.setLocation( targetRepoPath ); + c.addManagedRepository( testRepo ); + c.addManagedRepository( targetRepo ); + configuration.save( c ); + + + when(metadataRepository.getArtifacts(session, TEST_REPO_ID)).thenReturn(getArtifacts()); + repositoryMerger.merge(metadataRepository, TEST_REPO_ID, "target-rep"); + verify(metadataRepository).getArtifacts(session, TEST_REPO_ID); + assertTrue( Files.exists(mergedArtifact) ); + assertTrue( Files.exists(mavenMetadata) ); + assertTrue( Files.exists(pom) ); + } + + @Test + public void testMergeWithOutConflictArtifacts() + throws Exception + { + String sourceRepoId = "source-repo"; + ArtifactMetadata artifact1 = new ArtifactMetadata(); + artifact1.setNamespace( "org.testng" ); + artifact1.setProject( "testng" ); + artifact1.setVersion( "5.8" ); + artifact1.setProjectVersion( "5.8" ); + artifact1.setId( "testng-5.8-jdk15.jar" ); + artifact1.setRepositoryId( sourceRepoId ); + + List sourceRepoArtifactsList = getArtifacts(); + sourceRepoArtifactsList.add( artifact1 ); + List targetRepoArtifactsList = getArtifacts(); + + Configuration c = new Configuration(); + ManagedRepositoryConfiguration testRepo = new ManagedRepositoryConfiguration(); + testRepo.setId( TEST_REPO_ID ); + testRepo.setLocation( "target/test-repository" ); + + String sourceRepo = "src/test/resources/test-repository-with-conflict-artifacts"; + ManagedRepositoryConfiguration testRepoWithConflicts = new ManagedRepositoryConfiguration(); + testRepoWithConflicts.setId( sourceRepoId ); + testRepoWithConflicts.setLocation( sourceRepo ); + + RepositoryScanningConfiguration repoScanConfig = new RepositoryScanningConfiguration(); + List knownContentConsumers = new ArrayList<>(); + knownContentConsumers.add( "metadata-updater" ); + repoScanConfig.setKnownContentConsumers( knownContentConsumers ); + c.setRepositoryScanning( repoScanConfig ); + + c.addManagedRepository( testRepo ); + c.addManagedRepository( testRepoWithConflicts ); + configuration.save( c ); + + Path targetRepoFile = Paths.get( + "/target/test-repository/com/example/test/test-artifact/1.0-SNAPSHOT/test-artifact-1.0-20100308.230825-1.jar" ); + targetRepoFile.toFile().setReadOnly(); + + when(metadataRepository.getArtifacts(session, sourceRepoId)).thenReturn(sourceRepoArtifactsList); + when(metadataRepository.getArtifacts(session, TEST_REPO_ID)).thenReturn(targetRepoArtifactsList); + + assertEquals(1, repositoryMerger.getConflictingArtifacts(metadataRepository, sourceRepoId, + TEST_REPO_ID).size()); + verify(metadataRepository).getArtifacts(session, TEST_REPO_ID); + } + +} \ No newline at end of file diff --git a/archiva-modules/archiva-maven/archiva-maven-repository/src/test/java/org/apache/archiva/maven/repository/metadata/Maven2RepositoryStorageTest.java b/archiva-modules/archiva-maven/archiva-maven-repository/src/test/java/org/apache/archiva/maven/repository/metadata/Maven2RepositoryStorageTest.java new file mode 100644 index 000000000..c3d4036a5 --- /dev/null +++ b/archiva-modules/archiva-maven/archiva-maven-repository/src/test/java/org/apache/archiva/maven/repository/metadata/Maven2RepositoryStorageTest.java @@ -0,0 +1,64 @@ +package org.apache.archiva.maven.repository.metadata; + +/* + * 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.maven.repository.MavenManagedRepository; +import org.apache.archiva.metadata.repository.storage.RepositoryStorage; +import org.apache.archiva.test.utils.ArchivaSpringJUnit4ClassRunner; +import org.junit.Assert; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.test.context.ContextConfiguration; + +import javax.inject.Inject; +import javax.inject.Named; +import java.io.IOException; +import java.nio.file.Paths; + +/** + * @author Olivier Lamy + */ +@RunWith( ArchivaSpringJUnit4ClassRunner.class ) +@ContextConfiguration( { "classpath*:/spring-context-storage.xml", "classpath*:META-INF/spring-context.xml" } ) +public class Maven2RepositoryStorageTest +{ + @Inject + @Named( "repositoryStorage#maven2" ) + RepositoryStorage repositoryStorage; + + @Test + public void testGetLogicalPath() throws IOException { + String href = "/repository/internal/org/apache/maven/someartifact.jar"; + Assert.assertEquals( "/org/apache/maven/someartifact.jar", + repositoryStorage.getFilePath( href, MavenManagedRepository.newLocalInstance( "repo01", "repo01", Paths.get("target/repositories")) ) ); + + href = "repository/internal/org/apache/maven/someartifact.jar"; + Assert.assertEquals( "/org/apache/maven/someartifact.jar", + repositoryStorage.getFilePath( href, MavenManagedRepository.newLocalInstance( "repo01", "repo01", Paths.get("target/repositories") ) ) ); + + href = "repository/internal/org/apache/maven/"; + Assert.assertEquals( "/org/apache/maven/", repositoryStorage.getFilePath( href, MavenManagedRepository.newLocalInstance("repo01", "repo01", Paths.get("target/repositories")) ) ); + + href = "mypath"; + Assert.assertEquals( "/", repositoryStorage.getFilePath( href, MavenManagedRepository.newLocalInstance("repo01", "repo01", Paths.get("target/repositories")) ) ); + } + + +} + diff --git a/archiva-modules/archiva-maven/archiva-maven-repository/src/test/java/org/apache/archiva/maven/repository/metadata/MetadataToolsTest.java b/archiva-modules/archiva-maven/archiva-maven-repository/src/test/java/org/apache/archiva/maven/repository/metadata/MetadataToolsTest.java new file mode 100644 index 000000000..03d94f346 --- /dev/null +++ b/archiva-modules/archiva-maven/archiva-maven-repository/src/test/java/org/apache/archiva/maven/repository/metadata/MetadataToolsTest.java @@ -0,0 +1,691 @@ +package org.apache.archiva.maven.repository.metadata; + +/* + * 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.utils.VersionComparator; +import org.apache.archiva.configuration.ProxyConnectorConfiguration; +import org.apache.archiva.maven.repository.AbstractRepositoryLayerTestCase; +import org.apache.archiva.maven.repository.MavenManagedRepository; +import org.apache.archiva.maven.repository.metadata.storage.mock.MockConfiguration; +import org.apache.archiva.policies.CachedFailuresPolicy; +import org.apache.archiva.policies.ChecksumPolicy; +import org.apache.archiva.policies.ReleasesPolicy; +import org.apache.archiva.policies.SnapshotsPolicy; +import org.apache.archiva.repository.ManagedRepositoryContent; +import org.apache.archiva.repository.RemoteRepositoryContent; +import org.apache.archiva.repository.RepositoryContentProvider; +import org.apache.archiva.repository.content.ItemSelector; +import org.apache.archiva.repository.content.LayoutException; +import org.apache.archiva.repository.content.base.ArchivaItemSelector; +import org.apache.archiva.repository.metadata.RepositoryMetadataException; +import org.apache.archiva.repository.metadata.base.MetadataTools; +import org.apache.commons.io.FileUtils; +import org.apache.commons.lang3.StringUtils; +import org.junit.Test; +import org.springframework.test.context.ContextConfiguration; +import org.xml.sax.SAXException; +import org.xmlunit.builder.DiffBuilder; +import org.xmlunit.diff.Diff; +import org.xmlunit.diff.Difference; + +import javax.inject.Inject; +import javax.inject.Named; +import javax.xml.parsers.ParserConfigurationException; +import java.io.IOException; +import java.net.URISyntaxException; +import java.nio.charset.Charset; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import java.util.Set; + +import static org.junit.Assert.*; + +/** + * MetadataToolsTest + */ +@SuppressWarnings( "deprecation" ) +@ContextConfiguration ( + { "classpath*:/META-INF/spring-context.xml", "classpath:/spring-context-metadata-tools-test.xml" } ) +public class MetadataToolsTest + extends AbstractRepositoryLayerTestCase +{ + @Inject + @Named ( "metadataTools#test" ) + private MetadataTools tools; + + @Inject + @Named ( "archivaConfiguration#mock" ) + protected MockConfiguration config; + + private Path getRepositoryPath(String repoName) { + try + { + return Paths.get( Thread.currentThread( ).getContextClassLoader( ).getResource( "repositories/" + repoName ).toURI( ) ); + } + catch ( URISyntaxException e ) + { + throw new RuntimeException( "Could not resolve repository path " + e.getMessage( ), e ); + } + } + + @Test + public void testGatherSnapshotVersionsA() + throws Exception + { + removeProxyConnector( "test-repo", "apache-snapshots" ); + removeProxyConnector( "test-repo", "internal-snapshots" ); + removeProxyConnector( "test-repo", "snapshots.codehaus.org" ); + + assertSnapshotVersions( "snap_shots_a", "1.0-alpha-11-SNAPSHOT", + new String[]{ "1.0-alpha-11-SNAPSHOT", "1.0-alpha-11-20070221.194724-2", + "1.0-alpha-11-20070302.212723-3", "1.0-alpha-11-20070303.152828-4", + "1.0-alpha-11-20070305.215149-5", "1.0-alpha-11-20070307.170909-6", + "1.0-alpha-11-20070314.211405-9", "1.0-alpha-11-20070316.175232-11" } ); + } + + @Test + public void testGatherSnapshotVersionsAWithProxies() + throws Exception + { + // These proxied repositories do not need to exist for the purposes of this unit test, + // just the repository ids are important. + createProxyConnector( "test-repo", "apache-snapshots" ); + createProxyConnector( "test-repo", "internal-snapshots" ); + createProxyConnector( "test-repo", "snapshots.codehaus.org" ); + + assertSnapshotVersions( "snap_shots_a", "1.0-alpha-11-SNAPSHOT", + new String[]{ "1.0-alpha-11-SNAPSHOT", "1.0-alpha-11-20070221.194724-2", + "1.0-alpha-11-20070302.212723-3", "1.0-alpha-11-20070303.152828-4", + "1.0-alpha-11-20070305.215149-5", "1.0-alpha-11-20070307.170909-6", + "1.0-alpha-11-20070314.211405-9", "1.0-alpha-11-20070315.033030-10" + /* Arrives in via snapshots.codehaus.org proxy */, + "1.0-alpha-11-20070316.175232-11" } ); + } + + @Test + public void testGetRepositorySpecificName() + throws Exception + { + RemoteRepositoryContent repoJavaNet = + createRemoteRepositoryContent( "maven2-repository.dev.java.net", "Java.net Repository for Maven 2", + "http://download.java.net/maven/2/", "default" ); + RemoteRepositoryContent repoCentral = + createRemoteRepositoryContent( "central", "Central Global Repository", "http://repo1.maven.org/maven2/", + "default" ); + + String convertedName = + tools.getRepositorySpecificName( repoJavaNet, "commons-lang/commons-lang/maven-metadata.xml" ); + assertMetadataPath( "commons-lang/commons-lang/maven-metadata-maven2-repository.dev.java.net.xml", + convertedName ); + + convertedName = tools.getRepositorySpecificName( repoCentral, "commons-lang/commons-lang/maven-metadata.xml" ); + assertMetadataPath( "commons-lang/commons-lang/maven-metadata-central.xml", convertedName ); + } + + // TODO: replace with group tests +// public void testUpdateProjectBadArtifact() +// throws Exception +// { +// try +// { +// assertUpdatedProjectMetadata( "bad_artifact", null ); +// fail( "Should have thrown an IOException on a bad artifact." ); +// } +// catch ( IOException e ) +// { +// // Expected path +// } +// } + + @Test + public void testUpdateProjectNonExistingVersion() + throws Exception + { + ManagedRepositoryContent testRepo = createTestRepoContent(); + ItemSelector reference = ArchivaItemSelector.builder() + .withNamespace( "org.apache.archiva.metadata.tests" ) + .withProjectId( "missing_artifact" ).build(); + + prepProjectTestRepo( testRepo, reference ); + + // check metadata prior to update -- should contain the non-existing artifact version + assertProjectMetadata( testRepo, reference, "missing_artifact", + new String[]{ "1.0-SNAPSHOT", "1.1-SNAPSHOT", "1.2-SNAPSHOT" }, "1.2-SNAPSHOT", null ); + + tools.updateProjectMetadata( testRepo, reference ); + + // metadata should not contain the non-existing artifact version -- 1.1-SNAPSHOT + assertProjectMetadata( testRepo, reference, "missing_artifact", new String[]{ "1.0-SNAPSHOT", "1.2-SNAPSHOT" }, + "1.2-SNAPSHOT", null ); + } + + @Test + public void testUpdateProjectMissingMultipleVersions() + throws Exception + { + assertUpdatedProjectMetadata( "missing_metadata_b", + new String[]{ "1.0", "1.0.1", "2.0", "2.0.1", "2.0-20070821-dev" }, + "2.0-20070821-dev", "2.0-20070821-dev" ); + } + + @Test + public void testUpdateProjectMissingMultipleVersionsWithProxies() + throws Exception + { + // Attach the (bogus) proxies to the managed repo. + // These proxied repositories do not need to exist for the purposes of this unit test, + // just the repository ids are important. + createProxyConnector( "test-repo", "central" ); + createProxyConnector( "test-repo", "java.net" ); + + assertUpdatedProjectMetadata( "proxied_multi", + new String[]{ "1.0-spec" /* in java.net */, "1.0" /* in managed, and central */, + "1.0.1" /* in central */, "1.1" /* in managed */, "2.0-proposal-beta" + /* in java.net */, "2.0-spec" /* in java.net */, "2.0" + /* in central, and java.net */, "2.0.1" /* in java.net */, "2.1" + /* in managed */, "3.0" /* in central */, "3.1" /* in central */ }, "3.1", + "3.1" ); + } + + @Test + public void testUpdateProjectSimpleYetIncomplete() + throws Exception + { + assertUpdatedProjectMetadata( "incomplete_metadata_a", new String[]{ "1.0" }, "1.0", "1.0" ); + } + + @Test + public void testUpdateProjectSimpleYetMissing() + throws Exception + { + assertUpdatedProjectMetadata( "missing_metadata_a", new String[]{ "1.0" }, "1.0", "1.0" ); + } + + @Test + public void testUpdateVersionSimple10() + throws Exception + { + assertUpdatedReleaseVersionMetadata( "missing_metadata_a", "1.0" ); + } + + @Test + public void testUpdateVersionSimple20() + throws Exception + { + assertUpdatedReleaseVersionMetadata( "missing_metadata_b", "2.0" ); + } + + @Test + public void testUpdateVersionSimple20NotSnapshot() + throws Exception + { + assertUpdatedReleaseVersionMetadata( "missing_metadata_b", "2.0-20070821-dev" ); + } + + @Test + public void testUpdateVersionSnapshotA() + throws Exception + { + assertUpdatedSnapshotVersionMetadata( "snap_shots_a", "1.0-alpha-11-SNAPSHOT", "20070316", "175232", "11" ); + } + + @Test + public void testToPathFromVersionReference() + { + ItemSelector selector = ArchivaItemSelector.builder( ) + .withNamespace( "com.foo" ) + .withArtifactId( "foo-tool" ) + .withProjectId( "foo-tool" ) + .withVersion( "1.0" ).build( ); + + assertEquals( "com/foo/foo-tool/1.0/maven-metadata.xml", tools.toPath( selector ) ); + } + + @Test + public void testToPathFromProjectReference() + { + ItemSelector selector = ArchivaItemSelector.builder( ) + .withNamespace( "com.foo" ) + .withProjectId( "foo-tool" ) + .withArtifactId( "foo-tool" ).build( ); + + assertEquals( "com/foo/foo-tool/maven-metadata.xml", tools.toPath( selector ) ); + } + + @Test + public void testToProjectReferenceFooTools() + throws RepositoryMetadataException + { + assertProjectReference( "com.foo", "foo-tools", "com/foo/foo-tools/maven-metadata.xml" ); + } + + @Test + public void testToProjectReferenceAReallyLongPath() + throws RepositoryMetadataException + { + String groupId = "net.i.have.a.really.long.path.just.for.the.hell.of.it"; + String artifactId = "a"; + String path = "net/i/have/a/really/long/path/just/for/the/hell/of/it/a/maven-metadata.xml"; + + assertProjectReference( groupId, artifactId, path ); + } + + @Test + public void testToProjectReferenceCommonsLang() + throws RepositoryMetadataException + { + String groupId = "commons-lang"; + String artifactId = "commons-lang"; + String path = "commons-lang/commons-lang/maven-metadata.xml"; + + assertProjectReference( groupId, artifactId, path ); + } + + private void assertProjectReference( String groupId, String artifactId, String path ) + throws RepositoryMetadataException + { + ItemSelector reference = tools.toProjectSelector( path ); + + assertNotNull( "Reference should not be null.", reference ); + assertEquals( "ProjectReference.groupId", groupId, reference.getNamespace() ); + assertEquals( "ProjectReference.artifactId", artifactId, reference.getArtifactId() ); + } + + @Test + public void testToVersionedReferenceFooTool() + throws RepositoryMetadataException + { + String groupId = "com.foo"; + String artifactId = "foo-tool"; + String version = "1.0"; + String path = "com/foo/foo-tool/1.0/maven-metadata.xml"; + + assertVersionedReference( groupId, artifactId, version, path ); + } + + @Test + public void testToVersionedReferenceAReallyLongPath() + throws RepositoryMetadataException + { + String groupId = "net.i.have.a.really.long.path.just.for.the.hell.of.it"; + String artifactId = "a"; + String version = "1.1-alpha-1"; + String path = "net/i/have/a/really/long/path/just/for/the/hell/of/it/a/1.1-alpha-1/maven-metadata.xml"; + + assertVersionedReference( groupId, artifactId, version, path ); + } + + @Test + public void testToVersionedReferenceCommonsLang() + throws RepositoryMetadataException + { + String groupId = "commons-lang"; + String artifactId = "commons-lang"; + String version = "2.1"; + String path = "commons-lang/commons-lang/2.1/maven-metadata.xml"; + + assertVersionedReference( groupId, artifactId, version, path ); + } + + @Test + public void testToVersionedReferenceSnapshot() + throws RepositoryMetadataException + { + String groupId = "com.foo"; + String artifactId = "foo-connector"; + String version = "2.1-SNAPSHOT"; + String path = "com/foo/foo-connector/2.1-SNAPSHOT/maven-metadata.xml"; + + assertVersionedReference( groupId, artifactId, version, path ); + } + + private void assertVersionedReference( String groupId, String artifactId, String version, String path ) + throws RepositoryMetadataException + { + ItemSelector reference = tools.toVersionedSelector( path ); + assertNotNull( "Reference should not be null.", reference ); + + assertEquals( "VersionedReference.groupId", groupId, reference.getNamespace() ); + assertEquals( "VersionedReference.artifactId", artifactId, reference.getArtifactId() ); + assertEquals( "VersionedReference.version", version, reference.getVersion() ); + } + + private void assertSnapshotVersions( String artifactId, String version, String[] expectedVersions ) + throws Exception + { + Path repoRootDir = getRepositoryPath( "metadata-repository" ); + + ItemSelector reference = ArchivaItemSelector.builder( ) + .withNamespace( "org.apache.archiva.metadata.tests" ) + .withArtifactId( artifactId ) + .withProjectId( artifactId ) + .withVersion( version ).build( ); + + MavenManagedRepository repo = + createRepository( "test-repo", "Test Repository: " + name.getMethodName(), repoRootDir ); + + RepositoryContentProvider provider = applicationContext.getBean( "repositoryContentProvider#maven", RepositoryContentProvider.class ); + + ManagedRepositoryContent repoContent = + provider.createManagedContent( repo ); + + Set testedVersionSet = tools.gatherSnapshotVersions( repoContent, reference ); + + // Sort the list (for asserts) + List testedVersions = new ArrayList<>(); + testedVersions.addAll( testedVersionSet ); + Collections.sort( testedVersions, new VersionComparator() ); + + // Test the expected array of versions, to the actual tested versions + assertEquals( "Assert Snapshot Versions: length/size", expectedVersions.length, testedVersions.size() ); + + for ( int i = 0; i < expectedVersions.length; i++ ) + { + String actualVersion = testedVersions.get( i ); + assertEquals( "Snapshot Versions[" + i + "]", expectedVersions[i], actualVersion ); + } + } + + private void assertProjectMetadata( String expectedMetadata, ManagedRepositoryContent repository, + ItemSelector reference ) + throws LayoutException, IOException, SAXException, ParserConfigurationException + { + Path metadataFile = repository.getRepository().getRoot().getFilePath().resolve(tools.toPath( reference ) ); + String actualMetadata = org.apache.archiva.common.utils.FileUtils.readFileToString( metadataFile, Charset.defaultCharset() ); + + Diff detailedDiff = DiffBuilder.compare( expectedMetadata ).withTest( actualMetadata ).checkForSimilar().build(); + if ( detailedDiff.hasDifferences() ) + { + for ( Difference diff : detailedDiff.getDifferences() ) { + System.out.println( diff ); + } + // If it isn't similar, dump the difference. + assertEquals( expectedMetadata, actualMetadata ); + } + } + + private void assertMetadata( String expectedMetadata, ManagedRepositoryContent repository, + ItemSelector reference ) + throws LayoutException, IOException, SAXException, ParserConfigurationException + { + Path metadataFile = repository.getRepository().getRoot().getFilePath().resolve( tools.toPath( reference ) ); + String actualMetadata = org.apache.archiva.common.utils.FileUtils.readFileToString( metadataFile, Charset.defaultCharset() ); + + Diff detailedDiff = DiffBuilder.compare( expectedMetadata ).withTest( actualMetadata ).checkForSimilar().build(); + if ( detailedDiff.hasDifferences() ) + { + for ( Difference diff : detailedDiff.getDifferences() ) { + System.out.println( diff ); + } + // If it isn't similar, dump the difference. + assertEquals( expectedMetadata, actualMetadata ); + } + } + + private void assertMetadataPath( String expected, String actual ) + { + assertEquals( "Repository Specific Metadata Path", expected, actual ); + } + + private void assertUpdatedProjectMetadata( String artifactId, String[] expectedVersions, String latestVersion, + String releaseVersion ) + throws Exception + { + ManagedRepositoryContent testRepo = createTestRepoContent(); + ItemSelector reference = ArchivaItemSelector.builder( ) + .withNamespace( "org.apache.archiva.metadata.tests" ) + .withProjectId( artifactId ).build(); + + prepProjectTestRepo( testRepo, reference ); + + tools.updateProjectMetadata( testRepo, reference ); + + StringBuilder buf = new StringBuilder(); + buf.append( "\n" ); + buf.append( " " ).append( reference.getNamespace() ).append( "\n" ); + buf.append( " " ).append( reference.getProjectId() ).append( "\n" ); + // buf.append( " 1.0\n" ); + + if ( expectedVersions != null ) + { + buf.append( " \n" ); + if ( latestVersion != null ) + { + buf.append( " " ).append( latestVersion ).append( "\n" ); + } + if ( releaseVersion != null ) + { + buf.append( " " ).append( releaseVersion ).append( "\n" ); + } + + buf.append( " \n" ); + for ( int i = 0; i < expectedVersions.length; i++ ) + { + buf.append( " " ).append( expectedVersions[i] ).append( "\n" ); + } + buf.append( " \n" ); + buf.append( " \n" ); + } + buf.append( "" ); + + assertProjectMetadata( buf.toString(), testRepo, reference ); + } + + private void assertProjectMetadata( ManagedRepositoryContent testRepo, ItemSelector reference, + String artifactId, String[] expectedVersions, String latestVersion, + String releaseVersion ) + throws Exception + { + StringBuilder buf = new StringBuilder(); + buf.append( "\n" ); + buf.append( " " ).append( reference.getNamespace() ).append( "\n" ); + buf.append( " " ).append( reference.getProjectId() ).append( "\n" ); + + if ( expectedVersions != null ) + { + buf.append( " \n" ); + if ( latestVersion != null ) + { + buf.append( " " ).append( latestVersion ).append( "\n" ); + } + if ( releaseVersion != null ) + { + buf.append( " " ).append( releaseVersion ).append( "\n" ); + } + + buf.append( " \n" ); + for ( int i = 0; i < expectedVersions.length; i++ ) + { + buf.append( " " ).append( expectedVersions[i] ).append( "\n" ); + } + buf.append( " \n" ); + buf.append( " \n" ); + } + buf.append( "" ); + + assertProjectMetadata( buf.toString(), testRepo, reference ); + } + + + private void assertUpdatedReleaseVersionMetadata( String artifactId, String version ) + throws Exception + { + ManagedRepositoryContent testRepo = createTestRepoContent(); + + ItemSelector selector = ArchivaItemSelector.builder() + .withNamespace( "org.apache.archiva.metadata.tests" ) + .withProjectId( artifactId ) + .withArtifactId( artifactId ) + .withVersion( version ).build(); + + prepTestRepo( testRepo, selector ); + + tools.updateVersionMetadata( testRepo, selector ); + + StringBuilder buf = new StringBuilder(); + buf.append( "\n" ); + buf.append( " " ).append( selector.getNamespace() ).append( "\n" ); + buf.append( " " ).append( selector.getArtifactId() ).append( "\n" ); + buf.append( " " ).append( selector.getVersion() ).append( "\n" ); + buf.append( "" ); + + assertMetadata( buf.toString(), testRepo, selector ); + } + + private void assertUpdatedSnapshotVersionMetadata( String artifactId, String version, String expectedDate, + String expectedTime, String expectedBuildNumber ) + throws Exception + { + ManagedRepositoryContent testRepo = createTestRepoContent(); + ItemSelector reference = ArchivaItemSelector.builder() + .withNamespace( "org.apache.archiva.metadata.tests" ) + .withArtifactId( artifactId ) + .withProjectId( artifactId ) + .withVersion( version ).build(); + + prepTestRepo( testRepo, reference ); + + tools.updateVersionMetadata( testRepo, reference ); + + StringBuilder buf = new StringBuilder(); + buf.append( "\n" ); + buf.append( " " ).append( reference.getNamespace() ).append( "\n" ); + buf.append( " " ).append( reference.getArtifactId() ).append( "\n" ); + buf.append( " " ).append( reference.getVersion() ).append( "\n" ); + buf.append( " \n" ); + buf.append( " \n" ); + buf.append( " " ).append( expectedBuildNumber ).append( "\n" ); + buf.append( " " ); + buf.append( expectedDate ).append( "." ).append( expectedTime ); + buf.append( "\n" ); + buf.append( " \n" ); + buf.append( " " ).append( expectedDate ).append( expectedTime ).append( "\n" ); + buf.append( " \n" ); + buf.append( "" ); + + assertMetadata( buf.toString(), testRepo, reference ); + } + + private void removeProxyConnector( String sourceRepoId, String targetRepoId ) + { + ProxyConnectorConfiguration toRemove = null; + for ( ProxyConnectorConfiguration pcc : config.getConfiguration().getProxyConnectors() ) + { + if ( pcc.getTargetRepoId().equals( targetRepoId ) && pcc.getSourceRepoId().equals( sourceRepoId ) ) + { + toRemove = pcc; + } + } + if ( toRemove != null ) + { + config.getConfiguration().removeProxyConnector( toRemove ); + String prefix = "proxyConnectors.proxyConnector(" + "1" + ")"; // XXX + config.triggerChange( prefix + ".sourceRepoId", toRemove.getSourceRepoId() ); + config.triggerChange( prefix + ".targetRepoId", toRemove.getTargetRepoId() ); + config.triggerChange( prefix + ".proxyId", toRemove.getProxyId() ); + config.triggerChange( prefix + ".policies.releases", toRemove.getPolicy( "releases", "" ) ); + config.triggerChange( prefix + ".policies.checksum", toRemove.getPolicy( "checksum", "" ) ); + config.triggerChange( prefix + ".policies.snapshots", toRemove.getPolicy( "snapshots", "" ) ); + config.triggerChange( prefix + ".policies.cache-failures", toRemove.getPolicy( "cache-failures", "" ) ); + } + } + + private void createProxyConnector( String sourceRepoId, String targetRepoId ) + { + ProxyConnectorConfiguration connectorConfig = new ProxyConnectorConfiguration(); + connectorConfig.setSourceRepoId( sourceRepoId ); + connectorConfig.setTargetRepoId( targetRepoId ); + connectorConfig.addPolicy( ProxyConnectorConfiguration.POLICY_CHECKSUM, ChecksumPolicy.IGNORE.getId() ); + connectorConfig.addPolicy( ProxyConnectorConfiguration.POLICY_RELEASES, ReleasesPolicy.ALWAYS.getId() ); + connectorConfig.addPolicy( ProxyConnectorConfiguration.POLICY_SNAPSHOTS, SnapshotsPolicy.ALWAYS.getId() ); + connectorConfig.addPolicy( ProxyConnectorConfiguration.POLICY_CACHE_FAILURES, CachedFailuresPolicy.NO.getId() ); + + int count = config.getConfiguration().getProxyConnectors().size(); + config.getConfiguration().addProxyConnector( connectorConfig ); + + // Proper Triggering ... + String prefix = "proxyConnectors.proxyConnector(" + count + ")"; + config.triggerChange( prefix + ".sourceRepoId", connectorConfig.getSourceRepoId() ); + config.triggerChange( prefix + ".targetRepoId", connectorConfig.getTargetRepoId() ); + config.triggerChange( prefix + ".proxyId", connectorConfig.getProxyId() ); + config.triggerChange( prefix + ".policies.releases", connectorConfig.getPolicy( "releases", "" ) ); + config.triggerChange( prefix + ".policies.checksum", connectorConfig.getPolicy( "checksum", "" ) ); + config.triggerChange( prefix + ".policies.snapshots", connectorConfig.getPolicy( "snapshots", "" ) ); + config.triggerChange( prefix + ".policies.cache-failures", connectorConfig.getPolicy( "cache-failures", "" ) ); + } + + private ManagedRepositoryContent createTestRepoContent() + throws Exception + { + Path repoRoot = Paths.get( "target/metadata-tests/" + name.getMethodName() ); + if ( Files.exists(repoRoot) ) + { + org.apache.archiva.common.utils.FileUtils.deleteDirectory( repoRoot ); + } + + Files.createDirectories(repoRoot); + + MavenManagedRepository repoConfig = + createRepository( "test-repo", "Test Repository: " + name.getMethodName(), repoRoot ); + + RepositoryContentProvider provider = applicationContext.getBean( "repositoryContentProvider#maven", RepositoryContentProvider.class ); + + ManagedRepositoryContent repoContent = + provider.createManagedContent( repoConfig ); + return repoContent; + } + + private void prepProjectTestRepo( ManagedRepositoryContent repo, ItemSelector reference) + throws IOException + { + String groupDir = StringUtils.replaceChars( reference.getNamespace(), '.', '/' ); + String path = groupDir + "/" + reference.getArtifactId(); + + Path srcRepoDir = getRepositoryPath( "metadata-repository" ); + Path srcDir = srcRepoDir.resolve( path ); + Path destDir = repo.getRepository().getRoot().getFilePath().resolve( path ); + + assertTrue( "Source Dir exists: " + srcDir, Files.exists(srcDir) ); + Files.createDirectories(destDir); + + FileUtils.copyDirectory( srcDir.toFile(), destDir.toFile() ); + } + + private void prepTestRepo( ManagedRepositoryContent repo, ItemSelector reference ) + throws IOException + { + String groupDir = StringUtils.replaceChars( reference.getNamespace(), '.', '/' ); + String path = groupDir + "/" + reference.getArtifactId(); + + Path srcRepoDir = getRepositoryPath( "metadata-repository" ); + Path srcDir = srcRepoDir.resolve( path ); + Path destDir = repo.getRepository().getRoot().getFilePath().resolve( path ); + + assertTrue( "Source Dir exists: " + srcDir, Files.exists(srcDir) ); + Files.createDirectories(destDir); + + FileUtils.copyDirectory( srcDir.toFile(), destDir.toFile() ); + } + + +} diff --git a/archiva-modules/archiva-maven/archiva-maven-repository/src/test/java/org/apache/archiva/maven/repository/metadata/RepositoryMetadataReaderTest.java b/archiva-modules/archiva-maven/archiva-maven-repository/src/test/java/org/apache/archiva/maven/repository/metadata/RepositoryMetadataReaderTest.java new file mode 100644 index 000000000..f946f8390 --- /dev/null +++ b/archiva-modules/archiva-maven/archiva-maven-repository/src/test/java/org/apache/archiva/maven/repository/metadata/RepositoryMetadataReaderTest.java @@ -0,0 +1,94 @@ +package org.apache.archiva.maven.repository.metadata; + +/* + * 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.maven.metadata.MavenMetadataReader; +import org.apache.archiva.model.ArchivaRepositoryMetadata; +import org.apache.archiva.repository.metadata.RepositoryMetadataException; +import org.apache.archiva.test.utils.ArchivaBlockJUnit4ClassRunner; +import org.junit.Test; +import org.junit.runner.RunWith; + +import java.net.URISyntaxException; +import java.nio.file.Path; +import java.nio.file.Paths; + +/** + * RepositoryMetadataReaderTest + * + * + */ +@RunWith( ArchivaBlockJUnit4ClassRunner.class ) +public class RepositoryMetadataReaderTest + extends TestCase +{ + + private Path getRepositoryPath(String repoName) { + try + { + return Paths.get( Thread.currentThread( ).getContextClassLoader( ).getResource( "repositories/" + repoName ).toURI( ) ); + } + catch ( URISyntaxException e ) + { + throw new RuntimeException( "Could not resolve repository path " + e.getMessage( ), e ); + } + } + + @Test + public void testLoadSimple() + throws RepositoryMetadataException + { + Path defaultRepoDir = getRepositoryPath( "default-repository" ); + Path metadataFile = defaultRepoDir.resolve( "org/apache/maven/shared/maven-downloader/maven-metadata.xml" ); + + MavenMetadataReader metadataReader = new MavenMetadataReader( ); + + ArchivaRepositoryMetadata metadata = metadataReader.read( metadataFile ); + + assertNotNull( metadata ); + assertEquals( "Group Id", "org.apache.maven.shared", metadata.getGroupId() ); + assertEquals( "Artifact Id", "maven-downloader", metadata.getArtifactId() ); + assertEquals( "Released Version", "1.1", metadata.getReleasedVersion() ); + assertEquals( "List of Available Versions", 2, metadata.getAvailableVersions().size() ); + assertTrue( "Available version 1.0", metadata.getAvailableVersions().contains( "1.0" ) ); + assertTrue( "Available version 1.1", metadata.getAvailableVersions().contains( "1.1" ) ); + } + + @Test + public void testLoadComplex() + throws RepositoryMetadataException + { + Path defaultRepoDir = getRepositoryPath( "default-repository" ); + Path metadataFile = defaultRepoDir.resolve( "org/apache/maven/samplejar/maven-metadata.xml" ); + MavenMetadataReader metadataReader = new MavenMetadataReader( ); + + ArchivaRepositoryMetadata metadata = metadataReader.read( metadataFile ); + + assertNotNull( metadata ); + assertEquals( "Group Id", "org.apache.maven", metadata.getGroupId() ); + assertEquals( "Artifact Id", "samplejar", metadata.getArtifactId() ); + assertEquals( "Released Version", "2.0", metadata.getReleasedVersion() ); + assertEquals( "Latest Version", "6.0-SNAPSHOT", metadata.getLatestVersion() ); + assertEquals( "List of Available Versions", 18, metadata.getAvailableVersions().size() ); + assertTrue( "Available version 6.0-20060311.183228-10", + metadata.getAvailableVersions().contains( "6.0-20060311.183228-10" ) ); + assertTrue( "Available version 6.0-SNAPSHOT", metadata.getAvailableVersions().contains( "6.0-SNAPSHOT" ) ); + } +} diff --git a/archiva-modules/archiva-maven/archiva-maven-repository/src/test/java/org/apache/archiva/maven/repository/metadata/RepositoryMetadataWriterTest.java b/archiva-modules/archiva-maven/archiva-maven-repository/src/test/java/org/apache/archiva/maven/repository/metadata/RepositoryMetadataWriterTest.java new file mode 100644 index 000000000..dfe46ed92 --- /dev/null +++ b/archiva-modules/archiva-maven/archiva-maven-repository/src/test/java/org/apache/archiva/maven/repository/metadata/RepositoryMetadataWriterTest.java @@ -0,0 +1,76 @@ +package org.apache.archiva.maven.repository.metadata; + +/* + * 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.model.ArchivaRepositoryMetadata; +import org.apache.archiva.repository.metadata.base.RepositoryMetadataWriter; +import org.apache.archiva.test.utils.ArchivaBlockJUnit4ClassRunner; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.xmlunit.assertj.XmlAssert; + +import java.io.StringWriter; +import java.net.URISyntaxException; +import java.nio.charset.Charset; +import java.nio.file.Path; +import java.nio.file.Paths; + +/** + * RepositoryMetadataWriterTest + */ +@RunWith ( ArchivaBlockJUnit4ClassRunner.class ) +public class RepositoryMetadataWriterTest + extends TestCase +{ + private Path getRepositoryPath(String repoName) { + try + { + return Paths.get( Thread.currentThread( ).getContextClassLoader( ).getResource( "repositories/" + repoName ).toURI( ) ); + } + catch ( URISyntaxException e ) + { + throw new RuntimeException( "Could not resolve repository path " + e.getMessage( ), e ); + } + } + + @Test + public void testWriteSimple() + throws Exception + { + Path defaultRepoDir = getRepositoryPath( "default-repository" ); + Path expectedFile = defaultRepoDir.resolve( "org/apache/maven/shared/maven-downloader/maven-metadata.xml" ); + String expectedContent = org.apache.archiva.common.utils.FileUtils.readFileToString( expectedFile, Charset.defaultCharset() ); + + ArchivaRepositoryMetadata metadata = new ArchivaRepositoryMetadata(); + + metadata.setGroupId( "org.apache.maven.shared" ); + metadata.setArtifactId( "maven-downloader" ); + metadata.setVersion( "1.0" ); + metadata.setReleasedVersion( "1.1" ); + metadata.getAvailableVersions().add( "1.0" ); + metadata.getAvailableVersions().add( "1.1" ); + metadata.setLastUpdated( "20061212214311" ); + + StringWriter actual = new StringWriter(); + RepositoryMetadataWriter.write( metadata, actual ); + + XmlAssert.assertThat( actual.toString() ).and( expectedContent ).areIdentical(); + } +} diff --git a/archiva-modules/archiva-maven/archiva-maven-repository/src/test/java/org/apache/archiva/maven/repository/metadata/storage/Maven2RepositoryMetadataResolverMRM1411RepoGroupTest.java b/archiva-modules/archiva-maven/archiva-maven-repository/src/test/java/org/apache/archiva/maven/repository/metadata/storage/Maven2RepositoryMetadataResolverMRM1411RepoGroupTest.java new file mode 100644 index 000000000..730593083 --- /dev/null +++ b/archiva-modules/archiva-maven/archiva-maven-repository/src/test/java/org/apache/archiva/maven/repository/metadata/storage/Maven2RepositoryMetadataResolverMRM1411RepoGroupTest.java @@ -0,0 +1,555 @@ +package org.apache.archiva.maven.repository.metadata.storage; + +/* + * 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.configuration.ArchivaConfiguration; +import org.apache.archiva.configuration.Configuration; +import org.apache.archiva.configuration.ManagedRepositoryConfiguration; +import org.apache.archiva.configuration.ProxyConnectorConfiguration; +import org.apache.archiva.configuration.RemoteRepositoryConfiguration; +import org.apache.archiva.configuration.RepositoryGroupConfiguration; +import org.apache.archiva.filter.AllFilter; +import org.apache.archiva.filter.Filter; +import org.apache.archiva.metadata.model.ArtifactMetadata; +import org.apache.archiva.metadata.model.Dependency; +import org.apache.archiva.metadata.model.License; +import org.apache.archiva.metadata.model.MailingList; +import org.apache.archiva.metadata.model.ProjectVersionMetadata; +import org.apache.archiva.metadata.repository.storage.ReadMetadataRequest; +import org.apache.archiva.maven.common.proxy.WagonFactory; +import org.apache.archiva.maven.common.proxy.WagonFactoryRequest; +import org.apache.archiva.repository.RepositoryRegistry; +import org.apache.archiva.repository.base.RepositoryHandlerDependencies; +import org.apache.archiva.test.utils.ArchivaSpringJUnit4ClassRunner; +import org.apache.commons.io.FileUtils; +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 javax.inject.Inject; +import javax.inject.Named; +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + + +@RunWith ( ArchivaSpringJUnit4ClassRunner.class ) +@ContextConfiguration ( { "classpath*:/META-INF/spring-context.xml", "classpath:/spring-context.xml" } ) +public class Maven2RepositoryMetadataResolverMRM1411RepoGroupTest + extends TestCase +{ + private static final Filter ALL = new AllFilter(); + + @Inject + @Named ( "repositoryStorage#maven2") + private Maven2RepositoryStorage storage; + + private static final String TEST_REPO_ID = "test"; + + private static final String TEST_SNAP_REPO_ID = "tests"; + + private static final String TEST_REPO_GROUP_ID = "testrg"; + + 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"; + + @Inject + @Named ( "archivaConfiguration#default" ) + private ArchivaConfiguration configuration; + + @Inject + RepositoryRegistry repositoryRegistry; + + @SuppressWarnings( "unused" ) + @Inject + RepositoryHandlerDependencies repositoryHandlerDependencies; + + + private WagonFactory wagonFactory; + + ManagedRepositoryConfiguration testRepo; + + ManagedRepositoryConfiguration testRepoS; + + Configuration c; + + @Before + @Override + public void setUp() + throws Exception + { + super.setUp(); + + c = new Configuration(); + + testRepo = new ManagedRepositoryConfiguration(); + testRepo.setId( TEST_REPO_ID ); + testRepo.setLocation( Paths.get( "target/test-repository" ).toAbsolutePath().toString() ); + testRepo.setReleases( true ); + testRepo.setSnapshots( false ); + c.addManagedRepository( testRepo ); + + testRepoS = new ManagedRepositoryConfiguration(); + testRepoS.setId( TEST_SNAP_REPO_ID ); + testRepoS.setLocation( Paths.get( "target/test-repositorys" ).toAbsolutePath().toString() ); + testRepoS.setReleases( false ); + testRepoS.setSnapshots( true ); + c.addManagedRepository( testRepoS ); + + 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 ); + + ProxyConnectorConfiguration proxyConnectors = new ProxyConnectorConfiguration(); + proxyConnectors.setSourceRepoId( TEST_SNAP_REPO_ID ); + proxyConnectors.setTargetRepoId( TEST_REMOTE_REPO_ID ); + proxyConnectors.setDisabled( false ); + c.addProxyConnector( proxyConnectors ); + + List repos = new ArrayList<>(); + repos.add( TEST_REPO_ID ); + repos.add( TEST_SNAP_REPO_ID ); + + RepositoryGroupConfiguration repoGroup = new RepositoryGroupConfiguration(); + repoGroup.setId( TEST_REPO_GROUP_ID ); + repoGroup.setRepositories( repos ); + c.addRepositoryGroup( repoGroup ); + + configuration.save( c ); + repositoryRegistry.reload(); + + assertFalse( c.getManagedRepositories().get( 0 ).isSnapshots() ); + assertTrue( c.getManagedRepositories().get( 0 ).isReleases() ); + + assertTrue( c.getManagedRepositories().get( 1 ).isSnapshots() ); + assertFalse( c.getManagedRepositories().get( 1 ).isReleases() ); + + wagonFactory = mock( WagonFactory.class ); + + storage.setWagonFactory( wagonFactory ); + + Wagon wagon = new MockWagon(); + when( wagonFactory.getWagon( new WagonFactoryRequest().protocol( "wagon#http" ) ) ).thenReturn( wagon ); + } + + // Tests for MRM-1411 - START + @Test + public void testGetProjectVersionMetadataWithParentSuccessful() + throws Exception + { + copyTestArtifactWithParent( "src/test/resources/com/example/test/test-artifact-module-a", + "target/test-repository/com/example/test/test-artifact-module-a" ); + copyTestArtifactWithParent( "src/test/resources/com/example/test/test-artifact-root", + "target/test-repository/com/example/test/test-artifact-root" ); + copyTestArtifactWithParent( "src/test/resources/com/example/test/test-artifact-parent", + "target/test-repository/com/example/test/test-artifact-parent" ); + + ReadMetadataRequest readMetadataRequest = + new ReadMetadataRequest().repositoryId( TEST_REPO_ID ).namespace( "com.example.test" ).projectId( + "test-artifact-module-a" ).projectVersion( "1.0" ); + ProjectVersionMetadata metadata = storage.readProjectVersionMetadata( readMetadataRequest ); + + 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 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" ); + + List paths = new ArrayList<>(); + paths.add( "target/test-repository/com/example/test/test-artifact-module-a" ); + paths.add( "target/test-repository/com/example/test/test-artifact-parent" ); + paths.add( "target/test-repository/com/example/test/test-artifact-root" ); + + deleteTestArtifactWithParent( paths ); + } + + @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( "src/test/resources/com/example/test/test-artifact-module-a", + "target/test-repository/com/example/test/test-artifact-module-a" ); + copyTestArtifactWithParent( "src/test/resources/com/example/test/test-artifact-root", + "target/test-repository/com/example/test/test-artifact-root" ); + copyTestArtifactWithParent( "src/test/resources/com/example/test/test-artifact-parent", + "target/test-repository/com/example/test/test-artifact-parent" ); + + ReadMetadataRequest readMetadataRequest = + new ReadMetadataRequest().repositoryId( TEST_REPO_ID ).namespace( "com.example.test" ).projectId( + "test-artifact-module-a" ).projectVersion( "1.0" ); + ProjectVersionMetadata metadata = storage.readProjectVersionMetadata( readMetadataRequest ); + 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() ); + + List paths = new ArrayList<>(); + paths.add( "target/test-repository/com/example/test/test-artifact-module-a" ); + paths.add( "target/test-repository/com/example/test/test-artifact-parent" ); + paths.add( "target/test-repository/com/example/test/test-artifact-root" ); + + deleteTestArtifactWithParent( paths ); + } + + @Test + public void testGetProjectVersionMetadataWithParentNotInAnyRemoteRepo() + throws Exception + { + copyTestArtifactWithParent( "src/test/resources/com/example/test/test-artifact-module-a", + "target/test-repository/com/example/test/test-artifact-module-a" ); + + ReadMetadataRequest readMetadataRequest = + new ReadMetadataRequest().repositoryId( TEST_REPO_ID ).namespace( "com.example.test" ).projectId( + "missing-parent" ).projectVersion( "1.1" ); + + ProjectVersionMetadata metadata = storage.readProjectVersionMetadata( readMetadataRequest ); + + 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() ); + + List paths = new ArrayList<>(); + paths.add( "target/test-repository/com/example/test/test-artifact-module-a" ); + paths.add( "target/test-repository/com/example/test/test-artifact-parent" ); + paths.add( "target/test-repository/com/example/test/test-artifact-root" ); + + deleteTestArtifactWithParent( paths ); + } + + @Test + public void testGetProjectVersionMetadataWithParentSnapshotVersion() + throws Exception + { + copyTestArtifactWithParent( "target/test-classes/com/example/test/test-snapshot-artifact-module-a", + "target/test-repositorys/com/example/test/test-snapshot-artifact-module-a" ); + copyTestArtifactWithParent( "target/test-classes/com/example/test/test-snapshot-artifact-root", + "target/test-repositorys/com/example/test/test-snapshot-artifact-root" ); + copyTestArtifactWithParent( "src/test/resources/com/example/test/test-artifact-parent", + "target/test-repositorys/com/example/test/test-artifact-parent" ); + + ReadMetadataRequest readMetadataRequest = + new ReadMetadataRequest( TEST_SNAP_REPO_ID, "com.example.test", "test-snapshot-artifact-module-a", + "1.1-SNAPSHOT" ); + + ProjectVersionMetadata metadata = storage.readProjectVersionMetadata( readMetadataRequest ); + + MavenProjectFacet facet = (MavenProjectFacet) metadata.getFacet( MavenProjectFacet.FACET_ID ); + assertEquals( "jar", facet.getPackaging() ); + assertEquals( "com.example.test", facet.getParent().getGroupId() ); + assertEquals( "test-snapshot-artifact-root", facet.getParent().getArtifactId() ); + assertEquals( "1.1-SNAPSHOT", facet.getParent().getVersion() ); + assertEquals( "test-snapshot-artifact-module-a", facet.getArtifactId() ); + assertEquals( "com.example.test", facet.getGroupId() ); + assertNull( metadata.getCiManagement() ); + assertNotNull( metadata.getDescription() ); + + checkApacheLicense( metadata ); + + assertEquals( "1.1-SNAPSHOT", metadata.getId() ); + assertEquals( "Test Snapshot Artifact :: Module A", metadata.getName() ); + String path = "test-snapshot-artifact/trunk/test-snapshot-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 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" ); + + List paths = new ArrayList<>(); + paths.add( "target/test-repositorys/com/example/test/test-snapshot-artifact-module-a" ); + paths.add( "target/test-repositorys/com/example/test/test-snapshot-artifact-root" ); + deleteTestArtifactWithParent( paths ); + } + + @Test + public void testGetProjectVersionMetadataWithParentSnapshotVersionAndSnapNotAllowed() + throws Exception + { + copyTestArtifactWithParent( "target/test-classes/com/example/test/test-snapshot-artifact-module-a", + "target/test-repositorys/com/example/test/test-snapshot-artifact-module-a" ); + copyTestArtifactWithParent( "src/test/resources/com/example/test/test-artifact-parent", + "target/test-repositorys/com/example/test/test-artifact-parent" ); + copyTestArtifactWithParent( "src/test/resources/com/example/test/test-snapshot-artifact-root", + "target/test-repositorys/com/example/test/test-snapshot-artifact-root" ); + + ReadMetadataRequest readMetadataRequest = + new ReadMetadataRequest().repositoryId( TEST_SNAP_REPO_ID ).namespace( "com.example.test" ).projectId( + "test-snapshot-artifact-module-a" ).projectVersion( "1.1-SNAPSHOT" ); + ProjectVersionMetadata metadata = storage.readProjectVersionMetadata( readMetadataRequest ); + + MavenProjectFacet facet = (MavenProjectFacet) metadata.getFacet( MavenProjectFacet.FACET_ID ); + assertEquals( "jar", facet.getPackaging() ); + assertEquals( "com.example.test", facet.getParent().getGroupId() ); + assertEquals( "test-snapshot-artifact-root", facet.getParent().getArtifactId() ); + assertEquals( "1.1-SNAPSHOT", facet.getParent().getVersion() ); + assertEquals( "test-snapshot-artifact-module-a", facet.getArtifactId() ); + assertEquals( "com.example.test", facet.getGroupId() ); + assertNull( metadata.getCiManagement() ); + assertNotNull( metadata.getDescription() ); + + checkApacheLicense( metadata ); + + assertEquals( "1.1-SNAPSHOT", metadata.getId() ); + assertEquals( "Test Snapshot Artifact :: Module A", metadata.getName() ); + String path = "test-snapshot-artifact/trunk/test-snapshot-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 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" ); + + List paths = new ArrayList<>(); + paths.add( "target/test-repositorys/com/example/test/test-snapshot-artifact-module-a" ); + paths.add( "target/test-repositorys/com/example/test/test-snapshot-artifact-root" ); + + deleteTestArtifactWithParent( paths ); + } + + @Test + public void testGetProjectVersionMetadataWithParentSnapshotVersionAndSnapNotAllowed2() + throws Exception + { + copyTestArtifactWithParent( "src/test/resources/com/example/test/test-artifact-module-b", + "target/test-repository/com/example/test/test-artifact-module-b" ); + copyTestArtifactWithParent( "src/test/resources/com/example/test/test-artifact-parent", + "target/test-repository/com/example/test/test-artifact-parent" ); + copyTestArtifactWithParent( "src/test/resources/com/example/test/test-snapshot-artifact-root", + "target/test-repository/com/example/test/test-snapshot-artifact-root" ); + + ReadMetadataRequest readMetadataRequest = + new ReadMetadataRequest().repositoryId( TEST_REPO_ID ).namespace( "com.example.test" ).projectId( + "test-artifact-module-b" ).projectVersion( "1.0" ); + + ProjectVersionMetadata metadata = storage.readProjectVersionMetadata( readMetadataRequest ); + + MavenProjectFacet facet = (MavenProjectFacet) metadata.getFacet( MavenProjectFacet.FACET_ID ); + assertEquals( "jar", facet.getPackaging() ); + assertEquals( "com.example.test", facet.getParent().getGroupId() ); + assertEquals( "test-snapshot-artifact-root", facet.getParent().getArtifactId() ); + assertEquals( "1.1-SNAPSHOT", facet.getParent().getVersion() ); + assertEquals( "test-artifact-module-b", 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 B", metadata.getName() ); + String path = "test-snapshot-artifact/trunk/test-artifact-module-b"; + 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 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" ); + + List paths = new ArrayList<>(); + paths.add( "target/test-repository/com/example/test/test-artifact-module-b" ); + paths.add( "target/test-repository/com/example/test/test-snapshot-artifact-root" ); + + deleteTestArtifactWithParent( paths ); + } + // Tests for MRM-1411 - END + + private void assertDependency( Dependency dependency, String groupId, String artifactId, String version ) + { + assertDependency( dependency, groupId, artifactId, version, "compile" ); + } + + private void assertDependency( Dependency dependency, String groupId, String artifactId, String version, + String scope ) + { + assertEquals( artifactId, dependency.getArtifactId() ); + assertEquals( "jar", dependency.getType() ); + assertEquals( version, dependency.getVersion() ); + assertEquals( groupId, dependency.getNamespace() ); + assertEquals( scope, dependency.getScope() ); + assertNull( dependency.getClassifier() ); + assertNull( dependency.getSystemPath() ); + } + + private void assertArtifact( ArtifactMetadata artifact, String id, int size, String sha1, String md5 ) + { + assertEquals( id, artifact.getId() ); + assertEquals( md5, artifact.getMd5() ); + assertEquals( sha1, artifact.getSha1() ); + assertEquals( size, artifact.getSize() ); + assertEquals( "org.codehaus.plexus", artifact.getNamespace() ); + assertEquals( "plexus-spring", artifact.getProject() ); + assertEquals( "1.2", artifact.getVersion() ); + assertEquals( TEST_REPO_ID, artifact.getRepositoryId() ); + } + + private void assertMailingList( MailingList mailingList, String name, String archive, String post, String subscribe, + String unsubscribe, List otherArchives, boolean allowPost ) + { + assertEquals( archive, mailingList.getMainArchiveUrl() ); + if ( allowPost ) + { + assertEquals( post, mailingList.getPostAddress() ); + } + else + { + assertNull( mailingList.getPostAddress() ); + } + assertEquals( subscribe, mailingList.getSubscribeAddress() ); + assertEquals( unsubscribe, mailingList.getUnsubscribeAddress() ); + assertEquals( name, mailingList.getName() ); + assertEquals( otherArchives, mailingList.getOtherArchives() ); + } + + private void assertMailingList( String prefix, MailingList mailingList, String name, boolean allowPost, + String nabbleUrl ) + { + List otherArchives = new ArrayList<>(); + otherArchives.add( "http://www.mail-archive.com/" + prefix + "@archiva.apache.org" ); + if ( nabbleUrl != null ) + { + otherArchives.add( nabbleUrl ); + } + otherArchives.add( "http://markmail.org/list/org.apache.archiva." + prefix ); + assertMailingList( mailingList, name, "http://mail-archives.apache.org/mod_mbox/archiva-" + prefix + "/", + prefix + "@archiva.apache.org", prefix + "-subscribe@archiva.apache.org", + prefix + "-unsubscribe@archiva.apache.org", otherArchives, allowPost ); + } + + private void checkApacheLicense( ProjectVersionMetadata metadata ) + { + assertEquals( Arrays.asList( new License( "The Apache Software License, Version 2.0", + "http://www.apache.org/licenses/LICENSE-2.0.txt" ) ), + metadata.getLicenses() ); + } + + private void checkOrganizationApache( ProjectVersionMetadata metadata ) + { + assertEquals( "The Apache Software Foundation", metadata.getOrganization().getName() ); + assertEquals( "http://www.apache.org/", metadata.getOrganization().getUrl() ); + } + + private void deleteTestArtifactWithParent( List pathsToBeDeleted ) + throws IOException + { + for ( String path : pathsToBeDeleted ) + { + Path dir = Paths.get( org.apache.archiva.common.utils.FileUtils.getBasedir(), path ); + org.apache.archiva.common.utils.FileUtils.deleteDirectory( dir ); + + assertFalse( Files.exists(dir) ); + } + Path dest = Paths.get( org.apache.archiva.common.utils.FileUtils.getBasedir(), "target/test-repository/com/example/test/test-artifact-module-a" ); + Path parentPom = Paths.get( org.apache.archiva.common.utils.FileUtils.getBasedir(), "target/test-repository/com/example/test/test-artifact-parent" ); + Path rootPom = Paths.get( org.apache.archiva.common.utils.FileUtils.getBasedir(), "target/test-repository/com/example/test/test-artifact-root" ); + + org.apache.archiva.common.utils.FileUtils.deleteDirectory( dest ); + org.apache.archiva.common.utils.FileUtils.deleteDirectory( parentPom ); + org.apache.archiva.common.utils.FileUtils.deleteDirectory( rootPom ); + + assertFalse( Files.exists(dest) ); + assertFalse( Files.exists(parentPom) ); + assertFalse( Files.exists(rootPom) ); + } + + private Path copyTestArtifactWithParent( String srcPath, String destPath ) + throws IOException + { + Path src = Paths.get( org.apache.archiva.common.utils.FileUtils.getBasedir(), srcPath ); + Path dest = Paths.get( org.apache.archiva.common.utils.FileUtils.getBasedir(), destPath ); + + FileUtils.copyDirectory( src.toFile(), dest.toFile() ); + assertTrue( Files.exists(dest) ); + return dest; + } + +} diff --git a/archiva-modules/archiva-maven/archiva-maven-repository/src/test/java/org/apache/archiva/maven/repository/metadata/storage/Maven2RepositoryMetadataResolverMRM1411Test.java b/archiva-modules/archiva-maven/archiva-maven-repository/src/test/java/org/apache/archiva/maven/repository/metadata/storage/Maven2RepositoryMetadataResolverMRM1411Test.java new file mode 100644 index 000000000..c9d5c0222 --- /dev/null +++ b/archiva-modules/archiva-maven/archiva-maven-repository/src/test/java/org/apache/archiva/maven/repository/metadata/storage/Maven2RepositoryMetadataResolverMRM1411Test.java @@ -0,0 +1,459 @@ +package org.apache.archiva.maven.repository.metadata.storage; + +/* + * 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.configuration.ArchivaConfiguration; +import org.apache.archiva.configuration.Configuration; +import org.apache.archiva.configuration.ManagedRepositoryConfiguration; +import org.apache.archiva.configuration.ProxyConnectorConfiguration; +import org.apache.archiva.configuration.RemoteRepositoryConfiguration; +import org.apache.archiva.filter.AllFilter; +import org.apache.archiva.filter.Filter; +import org.apache.archiva.metadata.model.ArtifactMetadata; +import org.apache.archiva.metadata.model.Dependency; +import org.apache.archiva.metadata.model.License; +import org.apache.archiva.metadata.model.MailingList; +import org.apache.archiva.metadata.model.ProjectVersionMetadata; +import org.apache.archiva.metadata.repository.storage.ReadMetadataRequest; +import org.apache.archiva.metadata.repository.storage.RepositoryStorageRuntimeException; +import org.apache.archiva.maven.common.proxy.WagonFactory; +import org.apache.archiva.maven.common.proxy.WagonFactoryRequest; +import org.apache.archiva.repository.ReleaseScheme; +import org.apache.archiva.repository.RepositoryRegistry; +import org.apache.archiva.repository.base.RepositoryHandlerDependencies; +import org.apache.archiva.test.utils.ArchivaSpringJUnit4ClassRunner; +import org.apache.commons.io.FileUtils; +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 javax.inject.Inject; +import javax.inject.Named; +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashMap; +import java.util.List; + +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + +@RunWith ( ArchivaSpringJUnit4ClassRunner.class ) +@ContextConfiguration ( { "classpath*:/META-INF/spring-context.xml", "classpath:/spring-context.xml" } ) +public class Maven2RepositoryMetadataResolverMRM1411Test + extends TestCase +{ + private static final Filter ALL = new AllFilter(); + + @Inject + @Named ( "repositoryStorage#maven2") + private Maven2RepositoryStorage storage; + + 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"; + + @Inject + @Named ( "archivaConfiguration#default" ) + private ArchivaConfiguration configuration; + + @Inject + RepositoryRegistry repositoryRegistry; + + @SuppressWarnings( "unused" ) + @Inject + RepositoryHandlerDependencies repositoryHandlerDependencies; + + + private WagonFactory wagonFactory; + + ManagedRepositoryConfiguration testRepo; + + Configuration c; + + @Before + @Override + public void setUp() + throws Exception + { + super.setUp(); + + c = new Configuration(); + testRepo = new ManagedRepositoryConfiguration(); + testRepo.setId( TEST_REPO_ID ); + testRepo.setLocation( Paths.get( "target/test-repository" ).toAbsolutePath().toString() ); + testRepo.setReleases( true ); + testRepo.setSnapshots( true ); + 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 ); + + repositoryRegistry.reload(); + + assertTrue( c.getManagedRepositories().get( 0 ).isSnapshots() ); + assertTrue( c.getManagedRepositories().get( 0 ).isReleases() ); + + wagonFactory = mock( WagonFactory.class ); + + assertNotNull( storage ); + storage.setWagonFactory( wagonFactory ); + + Wagon wagon = new MockWagon(); + when( wagonFactory.getWagon( + new WagonFactoryRequest( "wagon#http", new HashMap() ) ) ).thenReturn( wagon ); + } + + // Tests for MRM-1411 - START + @Test + public void testGetProjectVersionMetadataWithParentSuccessful() + throws Exception + { + assertNotNull( storage ); + copyTestArtifactWithParent( "target/test-classes/com/example/test/test-artifact-module-a", + "target/test-repository/com/example/test/test-artifact-module-a" ); + copyTestArtifactWithParent( "src/test/resources/com/example/test/test-artifact-parent", + "target/test-repository/com/example/test/test-artifact-parent" ); + + copyTestArtifactWithParent( "target/test-classes/com/example/test/test-artifact-root", + "target/test-repository/com/example/test/test-artifact-root" ); + + ProjectVersionMetadata metadata = storage.readProjectVersionMetadata( + new ReadMetadataRequest( 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 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" ); + + List paths = new ArrayList<>(); + paths.add( "target/test-repository/com/example/test/test-artifact-module-a" ); + paths.add( "target/test-repository/com/example/test/test-artifact-parent" ); + paths.add( "target/test-repository/com/example/test/test-artifact-root" ); + + deleteTestArtifactWithParent( paths ); + } + + @Test + public void testGetProjectVersionMetadataWithParentNoRemoteReposConfigured() + throws Exception + { + assertNotNull( storage ); + // remove configuration + Configuration config = configuration.getConfiguration(); + RemoteRepositoryConfiguration remoteRepo = config.findRemoteRepositoryById( TEST_REMOTE_REPO_ID ); + config.removeRemoteRepository( remoteRepo ); + + configuration.save( config ); + assertNotNull( storage ); + + copyTestArtifactWithParent( "target/test-classes/com/example/test/test-artifact-module-a", + "target/test-repository/com/example/test/test-artifact-module-a" ); + + ProjectVersionMetadata metadata = storage.readProjectVersionMetadata( + new ReadMetadataRequest( 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() ); + + List paths = new ArrayList<>(); + paths.add( "target/test-repository/com/example/test/test-artifact-module-a" ); + paths.add( "target/test-repository/com/example/test/test-artifact-parent" ); + paths.add( "target/test-repository/com/example/test/test-artifact-root" ); + + deleteTestArtifactWithParent( paths ); + } + + @Test + public void testGetProjectVersionMetadataWithParentNotInAnyRemoteRepo() + throws Exception + { + assertNotNull( storage ); + copyTestArtifactWithParent( "target/test-classes/com/example/test/test-artifact-module-a", + "target/test-repository/com/example/test/test-artifact-module-a" ); + + ProjectVersionMetadata metadata = storage.readProjectVersionMetadata( + new ReadMetadataRequest( 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() ); + + List paths = new ArrayList<>(); + paths.add( "target/test-repository/com/example/test/test-artifact-module-a" ); + paths.add( "target/test-repository/com/example/test/test-artifact-parent" ); + paths.add( "target/test-repository/com/example/test/test-artifact-root" ); + + deleteTestArtifactWithParent( paths ); + } + + @Test + public void testGetProjectVersionMetadataWithParentSnapshotVersion() + throws Exception + { + + copyTestArtifactWithParent( "target/test-classes/com/example/test/test-snapshot-artifact-module-a", + "target/test-repository/com/example/test/test-snapshot-artifact-module-a" ); + + copyTestArtifactWithParent( "src/test/resources/com/example/test/test-artifact-parent", + "target/test-repository/com/example/test/test-artifact-parent" ); + + copyTestArtifactWithParent( "target/test-classes/com/example/test/test-snapshot-artifact-root", + "target/test-repository/com/example/test/test-snapshot-artifact-root" ); + + ProjectVersionMetadata metadata = storage.readProjectVersionMetadata( + new ReadMetadataRequest( TEST_REPO_ID, "com.example.test", "test-snapshot-artifact-module-a", + "1.1-SNAPSHOT" ) ); + + MavenProjectFacet facet = (MavenProjectFacet) metadata.getFacet( MavenProjectFacet.FACET_ID ); + assertEquals( "jar", facet.getPackaging() ); + assertEquals( "com.example.test", facet.getParent().getGroupId() ); + assertEquals( "test-snapshot-artifact-root", facet.getParent().getArtifactId() ); + assertEquals( "1.1-SNAPSHOT", facet.getParent().getVersion() ); + assertEquals( "test-snapshot-artifact-module-a", facet.getArtifactId() ); + assertEquals( "com.example.test", facet.getGroupId() ); + assertNull( metadata.getCiManagement() ); + assertNotNull( metadata.getDescription() ); + + checkApacheLicense( metadata ); + + assertEquals( "1.1-SNAPSHOT", metadata.getId() ); + assertEquals( "Test Snapshot Artifact :: Module A", metadata.getName() ); + String path = "test-snapshot-artifact/trunk/test-snapshot-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 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" ); + + List paths = new ArrayList<>(); + paths.add( "target/test-repository/com/example/test/test-snapshot-artifact-module-a" ); + paths.add( "target/test-repository/com/example/test/test-snapshot-artifact-root" ); + + deleteTestArtifactWithParent( paths ); + } + + @Test + public void testGetProjectVersionMetadataWithParentSnapshotVersionAndSnapNotAllowed() + throws Exception + { + testRepo.setSnapshots( false ); + configuration.save( c ); + repositoryRegistry.reload(); + assertFalse(repositoryRegistry.getManagedRepository(testRepo.getId()).getActiveReleaseSchemes().contains(ReleaseScheme.SNAPSHOT)); + assertFalse( c.getManagedRepositories().get( 0 ).isSnapshots() ); + copyTestArtifactWithParent( "target/test-classes/com/example/test/test-snapshot-artifact-module-a", + "target/test-repository/com/example/test/test-snapshot-artifact-module-a" ); + + try + { + ProjectVersionMetadata metadata = storage.readProjectVersionMetadata( + new ReadMetadataRequest( TEST_REPO_ID, "com.example.test", "test-snapshot-artifact-module-a", + "1.1-SNAPSHOT" ) ); + fail( "Should not be found" ); + } + catch ( RepositoryStorageRuntimeException e ) + { + } + + List paths = new ArrayList<>(); + paths.add( "target/test-repository/com/example/test/test-snapshot-artifact-module-a" ); + paths.add( "target/test-repository/com/example/test/test-snapshot-artifact-root" ); + + deleteTestArtifactWithParent( paths ); + } + // Tests for MRM-1411 - END + + private void assertDependency( Dependency dependency, String groupId, String artifactId, String version ) + { + assertDependency( dependency, groupId, artifactId, version, "compile" ); + } + + private void assertDependency( Dependency dependency, String groupId, String artifactId, String version, + String scope ) + { + assertEquals( artifactId, dependency.getArtifactId() ); + assertEquals( "jar", dependency.getType() ); + assertEquals( version, dependency.getVersion() ); + assertEquals( groupId, dependency.getNamespace() ); + assertEquals( scope, dependency.getScope() ); + assertNull( dependency.getClassifier() ); + assertNull( dependency.getSystemPath() ); + } + + private void assertArtifact( ArtifactMetadata artifact, String id, int size, String sha1, String md5 ) + { + assertEquals( id, artifact.getId() ); + assertEquals( md5, artifact.getMd5() ); + assertEquals( sha1, artifact.getSha1() ); + assertEquals( size, artifact.getSize() ); + assertEquals( "org.codehaus.plexus", artifact.getNamespace() ); + assertEquals( "plexus-spring", artifact.getProject() ); + assertEquals( "1.2", artifact.getVersion() ); + assertEquals( TEST_REPO_ID, artifact.getRepositoryId() ); + } + + private void assertMailingList( MailingList mailingList, String name, String archive, String post, String subscribe, + String unsubscribe, List otherArchives, boolean allowPost ) + { + assertEquals( archive, mailingList.getMainArchiveUrl() ); + if ( allowPost ) + { + assertEquals( post, mailingList.getPostAddress() ); + } + else + { + assertNull( mailingList.getPostAddress() ); + } + assertEquals( subscribe, mailingList.getSubscribeAddress() ); + assertEquals( unsubscribe, mailingList.getUnsubscribeAddress() ); + assertEquals( name, mailingList.getName() ); + assertEquals( otherArchives, mailingList.getOtherArchives() ); + } + + private void assertMailingList( String prefix, MailingList mailingList, String name, boolean allowPost, + String nabbleUrl ) + { + List otherArchives = new ArrayList<>(); + otherArchives.add( "http://www.mail-archive.com/" + prefix + "@archiva.apache.org" ); + if ( nabbleUrl != null ) + { + otherArchives.add( nabbleUrl ); + } + otherArchives.add( "http://markmail.org/list/org.apache.archiva." + prefix ); + assertMailingList( mailingList, name, "http://mail-archives.apache.org/mod_mbox/archiva-" + prefix + "/", + prefix + "@archiva.apache.org", prefix + "-subscribe@archiva.apache.org", + prefix + "-unsubscribe@archiva.apache.org", otherArchives, allowPost ); + } + + private void checkApacheLicense( ProjectVersionMetadata metadata ) + { + assertEquals( Arrays.asList( new License( "The Apache Software License, Version 2.0", + "http://www.apache.org/licenses/LICENSE-2.0.txt" ) ), + metadata.getLicenses() ); + } + + private void checkOrganizationApache( ProjectVersionMetadata metadata ) + { + assertEquals( "The Apache Software Foundation", metadata.getOrganization().getName() ); + assertEquals( "http://www.apache.org/", metadata.getOrganization().getUrl() ); + } + + private void deleteTestArtifactWithParent( List pathsToBeDeleted ) + throws IOException + { + for ( String path : pathsToBeDeleted ) + { + Path dir = Paths.get( org.apache.archiva.common.utils.FileUtils.getBasedir(), path ); + org.apache.archiva.common.utils.FileUtils.deleteDirectory( dir ); + + assertFalse(Files.exists( dir) ); + } + Path dest = Paths.get( org.apache.archiva.common.utils.FileUtils.getBasedir(), "target/test-repository/com/example/test/test-artifact-module-a" ); + Path parentPom = + Paths.get( org.apache.archiva.common.utils.FileUtils.getBasedir(), "target/test-repository/com/example/test/test-artifact-parent" ); + Path rootPom = Paths.get( org.apache.archiva.common.utils.FileUtils.getBasedir(), "target/test-repository/com/example/test/test-artifact-root" ); + + org.apache.archiva.common.utils.FileUtils.deleteDirectory( dest ); + org.apache.archiva.common.utils.FileUtils.deleteDirectory( parentPom ); + org.apache.archiva.common.utils.FileUtils.deleteDirectory( rootPom ); + + assertFalse( Files.exists(dest) ); + assertFalse( Files.exists(parentPom) ); + assertFalse( Files.exists(rootPom) ); + } + + private Path copyTestArtifactWithParent( String srcPath, String destPath ) + throws IOException + { + Path src = Paths.get( org.apache.archiva.common.utils.FileUtils.getBasedir(), srcPath ); + Path dest = Paths.get( org.apache.archiva.common.utils.FileUtils.getBasedir(), destPath ); + + FileUtils.copyDirectory( src.toFile(), dest.toFile() ); + assertTrue( Files.exists(dest) ); + return dest; + } + +} diff --git a/archiva-modules/archiva-maven/archiva-maven-repository/src/test/java/org/apache/archiva/maven/repository/metadata/storage/Maven2RepositoryMetadataResolverManagedReleaseTest.java b/archiva-modules/archiva-maven/archiva-maven-repository/src/test/java/org/apache/archiva/maven/repository/metadata/storage/Maven2RepositoryMetadataResolverManagedReleaseTest.java new file mode 100644 index 000000000..a130831c5 --- /dev/null +++ b/archiva-modules/archiva-maven/archiva-maven-repository/src/test/java/org/apache/archiva/maven/repository/metadata/storage/Maven2RepositoryMetadataResolverManagedReleaseTest.java @@ -0,0 +1,147 @@ +package org.apache.archiva.maven.repository.metadata.storage; + +/* + * 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.filter.AllFilter; +import org.apache.archiva.filter.Filter; +import org.apache.archiva.metadata.model.ProjectVersionMetadata; +import org.apache.archiva.metadata.repository.storage.ReadMetadataRequest; +import org.apache.archiva.metadata.repository.storage.RepositoryStorageRuntimeException; +import org.apache.archiva.maven.common.proxy.WagonFactory; +import org.apache.archiva.repository.RepositoryRegistry; +import org.apache.archiva.repository.base.RepositoryHandlerDependencies; +import org.junit.Before; +import org.junit.Test; + +import javax.inject.Inject; +import javax.inject.Named; + + +public class Maven2RepositoryMetadataResolverManagedReleaseTest + extends Maven2RepositoryMetadataResolverTest +{ + private static final Filter ALL = new AllFilter(); + + @Inject + @Named ( "repositoryStorage#maven2") + private Maven2RepositoryStorage storage; + + @Inject + RepositoryRegistry repositoryRegistry; + + @SuppressWarnings( "unused" ) + @Inject + RepositoryHandlerDependencies repositoryHandlerDependencies; + + + 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"; + + private WagonFactory wagonFactory; + + @Before + @Override + public void setUp() + throws Exception + { + super.setUp(); + + testRepo.setReleases( true ); + testRepo.setSnapshots( false ); + + configuration.save( c ); + + repositoryRegistry.reload(); + + assertFalse( c.getManagedRepositories().get( 0 ).isSnapshots() ); + assertTrue( c.getManagedRepositories().get( 0 ).isReleases() ); + + } + + @Test + @Override + public void testModelWithJdkProfileActivation() + throws Exception + { + // skygo IMHO must fail because TEST_REPO_ID ( is snap ,no release) and we seek for a snapshot + + ReadMetadataRequest readMetadataRequest = + new ReadMetadataRequest().repositoryId( TEST_REPO_ID ).namespace( "org.apache.maven" ).projectId( + "maven-archiver" ).projectVersion( "2.4.1" ); + + ProjectVersionMetadata metadata = storage.readProjectVersionMetadata( readMetadataRequest ); + } + + @Test (expected = RepositoryStorageRuntimeException.class) + @Override + public void testGetProjectVersionMetadataForTimestampedSnapshotMissingMetadata() + throws Exception + { + ReadMetadataRequest readMetadataRequest = + new ReadMetadataRequest().repositoryId( TEST_REPO_ID ).namespace( "com.example.test" ).projectId( + "missing-metadata" ).projectVersion( "1.0-SNAPSHOT" ); + storage.readProjectVersionMetadata( readMetadataRequest ); + } + + @Test (expected = RepositoryStorageRuntimeException.class) + @Override + public void testGetProjectVersionMetadataForTimestampedSnapshotMalformedMetadata() + throws Exception + { + ReadMetadataRequest readMetadataRequest = + new ReadMetadataRequest().repositoryId( TEST_REPO_ID ).namespace( "com.example.test" ).projectVersion( + "malformed-metadata" ).projectVersion( "1.0-SNAPSHOT" ); + storage.readProjectVersionMetadata( readMetadataRequest ); + } + + @Test (expected = RepositoryStorageRuntimeException.class) + @Override + public void testGetProjectVersionMetadataForTimestampedSnapshot() + throws Exception + { + super.testGetProjectVersionMetadataForTimestampedSnapshot(); + } + + + @Test (expected = RepositoryStorageRuntimeException.class) + @Override + public void testGetProjectVersionMetadataForTimestampedSnapshotIncompleteMetadata() + throws Exception + { + super.testGetProjectVersionMetadataForTimestampedSnapshotIncompleteMetadata(); + } + +} diff --git a/archiva-modules/archiva-maven/archiva-maven-repository/src/test/java/org/apache/archiva/maven/repository/metadata/storage/Maven2RepositoryMetadataResolverManagedSnapshotTest.java b/archiva-modules/archiva-maven/archiva-maven-repository/src/test/java/org/apache/archiva/maven/repository/metadata/storage/Maven2RepositoryMetadataResolverManagedSnapshotTest.java new file mode 100644 index 000000000..dce2ef02f --- /dev/null +++ b/archiva-modules/archiva-maven/archiva-maven-repository/src/test/java/org/apache/archiva/maven/repository/metadata/storage/Maven2RepositoryMetadataResolverManagedSnapshotTest.java @@ -0,0 +1,146 @@ +package org.apache.archiva.maven.repository.metadata.storage; + +/* + * 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.filter.AllFilter; +import org.apache.archiva.filter.Filter; +import org.apache.archiva.metadata.model.ProjectVersionMetadata; +import org.apache.archiva.metadata.repository.storage.ReadMetadataRequest; +import org.apache.archiva.metadata.repository.storage.RepositoryStorageRuntimeException; +import org.apache.archiva.repository.RepositoryRegistry; +import org.apache.archiva.repository.base.RepositoryHandlerDependencies; +import org.junit.Before; +import org.junit.Test; + +import javax.inject.Inject; +import javax.inject.Named; + +public class Maven2RepositoryMetadataResolverManagedSnapshotTest + extends Maven2RepositoryMetadataResolverTest +{ + private static final Filter ALL = new AllFilter(); + + @Inject + @Named ( "repositoryStorage#maven2") + private Maven2RepositoryStorage storage; + + @Inject + RepositoryRegistry repositoryRegistry; + + @SuppressWarnings( "unused" ) + @Inject + RepositoryHandlerDependencies repositoryHandlerDependencies; + + + 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"; + + + @Before + @Override + public void setUp() + throws Exception + { + super.setUp(); + + testRepo.setReleases( false ); + testRepo.setSnapshots( true ); + + configuration.save( c ); + + repositoryRegistry.reload(); + + assertTrue( c.getManagedRepositories().get( 0 ).isSnapshots() ); + assertFalse( c.getManagedRepositories().get( 0 ).isReleases() ); + } + + @Test (expected = RepositoryStorageRuntimeException.class) + @Override + public void testModelWithJdkProfileActivation() + throws Exception + { + // skygo IMHO must fail because TEST_REPO_ID ( is snap ,no release) and we seek for a snapshot + + ReadMetadataRequest readMetadataRequest = + new ReadMetadataRequest().repositoryId( TEST_REPO_ID ).namespace( "org.apache.maven" ).projectId( + "maven-archiver" ).projectVersion( "2.4.1" ); + + ProjectVersionMetadata metadata = storage.readProjectVersionMetadata( readMetadataRequest ); + } + + @Test (expected = RepositoryStorageRuntimeException.class) + @Override + public void testGetProjectVersionMetadataForMislocatedPom() + throws Exception + { + ReadMetadataRequest readMetadataRequest = + new ReadMetadataRequest().repositoryId( TEST_REPO_ID ).namespace( "com.example.test" ).projectId( + "mislocated-pom" ).projectVersion( "1.0" ); + storage.readProjectVersionMetadata( readMetadataRequest ); + + } + + @Test + @Override + public void testGetProjectVersionMetadata() + throws Exception + { + // super test is on release + } + + @Test (expected = RepositoryStorageRuntimeException.class) + @Override + public void testGetProjectVersionMetadataForInvalidPom() + throws Exception + { + ReadMetadataRequest readMetadataRequest = + new ReadMetadataRequest().repositoryId( TEST_REPO_ID ).namespace( "com.example.test" ).projectId( + "invalid-pom" ).projectVersion( "1.0" ); + storage.readProjectVersionMetadata( readMetadataRequest ); + } + + @Test (expected = RepositoryStorageRuntimeException.class) + @Override + public void testGetProjectVersionMetadataForMissingPom() + throws Exception + { + ReadMetadataRequest readMetadataRequest = + new ReadMetadataRequest().repositoryId( TEST_REPO_ID ).namespace( "com.example.test" ).projectId( + "missing-pom" ).projectVersion( "1.0" ); + storage.readProjectVersionMetadata( readMetadataRequest ); + } +} diff --git a/archiva-modules/archiva-maven/archiva-maven-repository/src/test/java/org/apache/archiva/maven/repository/metadata/storage/Maven2RepositoryMetadataResolverTest.java b/archiva-modules/archiva-maven/archiva-maven-repository/src/test/java/org/apache/archiva/maven/repository/metadata/storage/Maven2RepositoryMetadataResolverTest.java new file mode 100644 index 000000000..109ccacb1 --- /dev/null +++ b/archiva-modules/archiva-maven/archiva-maven-repository/src/test/java/org/apache/archiva/maven/repository/metadata/storage/Maven2RepositoryMetadataResolverTest.java @@ -0,0 +1,820 @@ +package org.apache.archiva.maven.repository.metadata.storage; + +/* + * 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.configuration.ArchivaConfiguration; +import org.apache.archiva.configuration.Configuration; +import org.apache.archiva.configuration.ManagedRepositoryConfiguration; +import org.apache.archiva.configuration.ProxyConnectorConfiguration; +import org.apache.archiva.configuration.RemoteRepositoryConfiguration; +import org.apache.archiva.configuration.RepositoryScanningConfiguration; +import org.apache.archiva.filter.AllFilter; +import org.apache.archiva.filter.ExcludesFilter; +import org.apache.archiva.filter.Filter; +import org.apache.archiva.maven.metadata.model.MavenArtifactFacet; +import org.apache.archiva.metadata.model.ArtifactMetadata; +import org.apache.archiva.metadata.model.Dependency; +import org.apache.archiva.metadata.model.License; +import org.apache.archiva.metadata.model.MailingList; +import org.apache.archiva.metadata.model.ProjectVersionMetadata; +import org.apache.archiva.metadata.repository.storage.ReadMetadataRequest; +import org.apache.archiva.metadata.repository.storage.RepositoryStorageMetadataInvalidException; +import org.apache.archiva.metadata.repository.storage.RepositoryStorageMetadataNotFoundException; +import org.apache.archiva.maven.common.proxy.WagonFactory; +import org.apache.archiva.maven.common.proxy.WagonFactoryRequest; +import org.apache.archiva.repository.RepositoryRegistry; +import org.apache.archiva.repository.base.RepositoryHandlerDependencies; +import org.apache.archiva.test.utils.ArchivaSpringJUnit4ClassRunner; +import org.apache.commons.io.FileUtils; +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 javax.inject.Inject; +import javax.inject.Named; +import java.io.IOException; +import java.net.URL; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.nio.file.StandardCopyOption; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; +import java.util.Collections; +import java.util.Comparator; +import java.util.List; + +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + +@RunWith ( ArchivaSpringJUnit4ClassRunner.class ) +@ContextConfiguration ( { "classpath*:/META-INF/spring-context.xml", "classpath:/spring-context.xml" } ) +public class Maven2RepositoryMetadataResolverTest + extends TestCase +{ + private static final Filter ALL = new AllFilter(); + + @Inject + @Named ( "repositoryStorage#maven2" ) + private Maven2RepositoryStorage storage; + + @Inject + RepositoryRegistry repositoryRegistry; + + @SuppressWarnings( "unused" ) + @Inject + RepositoryHandlerDependencies repositoryHandlerDependencies; + + + 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"; + + @Inject + @Named ( "archivaConfiguration#default" ) + protected ArchivaConfiguration configuration; + + private WagonFactory wagonFactory; + + ManagedRepositoryConfiguration testRepo; + + Configuration c; + + @Before + @Override + public void setUp() + throws Exception + { + super.setUp(); + + c = new Configuration(); + + c.setVersion("2.0"); + testRepo = new ManagedRepositoryConfiguration(); + testRepo.setId( TEST_REPO_ID ); + testRepo.setLocation( Paths.get( "target/test-repository" ).toAbsolutePath().toString() ); + testRepo.setReleases( true ); + testRepo.setSnapshots( true ); + 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 ); + + RepositoryScanningConfiguration scCfg = new RepositoryScanningConfiguration(); + c.setRepositoryScanning(scCfg); + + configuration.save( c ); + assertFalse(configuration.isDefaulted()); + repositoryRegistry.reload(); + + assertTrue( c.getManagedRepositories().get( 0 ).isSnapshots() ); + assertTrue( c.getManagedRepositories().get( 0 ).isReleases() ); + + wagonFactory = mock( WagonFactory.class ); + + storage.setWagonFactory( wagonFactory ); + + Wagon wagon = new MockWagon(); + when( wagonFactory.getWagon( new WagonFactoryRequest().protocol( "wagon#http" ) ) ).thenReturn( wagon ); + } + + @Test + public void testModelWithJdkProfileActivation() + throws Exception + { + ReadMetadataRequest readMetadataRequest = + new ReadMetadataRequest().repositoryId( TEST_REPO_ID ).namespace( "org.apache.maven" ).projectId( + "maven-archiver" ).projectVersion( "2.4.1" ); + ProjectVersionMetadata metadata = storage.readProjectVersionMetadata( readMetadataRequest ); + MavenProjectFacet facet = (MavenProjectFacet) metadata.getFacet( MavenProjectFacet.FACET_ID ); + } + + @Test + public void testGetProjectVersionMetadata() + throws Exception + { + ProjectVersionMetadata metadata = storage.readProjectVersionMetadata( + new ReadMetadataRequest( TEST_REPO_ID, "org.apache.archiva", "archiva-common", "1.2.1" ) ); + MavenProjectFacet facet = (MavenProjectFacet) metadata.getFacet( MavenProjectFacet.FACET_ID ); + assertEquals( "jar", facet.getPackaging() ); + assertEquals( "http://archiva.apache.org/ref/1.2.1/archiva-base/archiva-common", metadata.getUrl() ); + assertEquals( "org.apache.archiva", facet.getParent().getGroupId() ); + assertEquals( "archiva-base", facet.getParent().getArtifactId() ); + assertEquals( "1.2.1", facet.getParent().getVersion() ); + assertEquals( "archiva-common", facet.getArtifactId() ); + assertEquals( "org.apache.archiva", facet.getGroupId() ); + assertEquals( "continuum", metadata.getCiManagement().getSystem() ); + assertEquals( "http://vmbuild.apache.org/continuum", metadata.getCiManagement().getUrl() ); + assertNotNull( metadata.getDescription() ); + // TODO: this would be better +// assertEquals( +// "Archiva is an application for managing one or more remote repositories, including administration, artifact handling, browsing and searching.", +// metadata.getDescription() ); + assertEquals( "1.2.1", metadata.getId() ); + assertEquals( "jira", metadata.getIssueManagement().getSystem() ); + assertEquals( "http://jira.codehaus.org/browse/MRM", metadata.getIssueManagement().getUrl() ); + checkApacheLicense( metadata ); + assertEquals( "Archiva Base :: Common", metadata.getName() ); + String path = "archiva/tags/archiva-1.2.1/archiva-modules/archiva-base/archiva-common"; + assertEquals( ASF_SCM_CONN_BASE + path, metadata.getScm().getConnection() ); + assertEquals( ASF_SCM_DEV_CONN_BASE + path, metadata.getScm().getDeveloperConnection() ); + assertEquals( ASF_SCM_VIEWVC_BASE + path, metadata.getScm().getUrl() ); + checkOrganizationApache( metadata ); + + assertEquals( 4, metadata.getMailingLists().size() ); + assertMailingList( "users", metadata.getMailingLists().get( 0 ), "Archiva User List", true, + "http://www.nabble.com/archiva-users-f16426.html" ); + assertMailingList( "dev", metadata.getMailingLists().get( 1 ), "Archiva Developer List", true, + "http://www.nabble.com/archiva-dev-f16427.html" ); + assertMailingList( "commits", metadata.getMailingLists().get( 2 ), "Archiva Commits List", false, null ); + assertMailingList( "issues", metadata.getMailingLists().get( 3 ), "Archiva Issues List", false, + "http://www.nabble.com/Archiva---Issues-f29617.html" ); + + List dependencies = metadata.getDependencies(); + assertEquals( 10, dependencies.size() ); + assertDependency( dependencies.get( 0 ), "commons-lang", "commons-lang", "2.2" ); + assertDependency( dependencies.get( 1 ), "commons-io", "commons-io", "1.4" ); + assertDependency( dependencies.get( 2 ), "org.slf4j", "slf4j-api", "1.5.0" ); + assertDependency( dependencies.get( 3 ), "org.codehaus.plexus", "plexus-component-api", "1.0-alpha-22" ); + assertDependency( dependencies.get( 4 ), "org.codehaus.plexus", "plexus-spring", "1.2", "test" ); + assertDependency( dependencies.get( 5 ), "xalan", "xalan", "2.7.0" ); + assertDependency( dependencies.get( 6 ), "dom4j", "dom4j", "1.6.1", "test" ); + assertDependency( dependencies.get( 7 ), "junit", "junit", "3.8.1", "test" ); + assertDependency( dependencies.get( 8 ), "easymock", "easymock", "1.2_Java1.3", "test" ); + assertDependency( dependencies.get( 9 ), "easymock", "easymockclassextension", "1.2", "test" ); + + assertEquals( 8, metadata.getProperties().size() ); + assertEquals( "http://www.apache.org/images/asf_logo_wide.gif", metadata.getProperties().get("organization.logo") ); + } + + @Test + public void testGetArtifactMetadata() + throws Exception + { + Collection springArtifacts = storage.readArtifactsMetadata( + new ReadMetadataRequest( TEST_REPO_ID, "org.codehaus.plexus", "plexus-spring", "1.2", ALL ) ); + List artifacts = new ArrayList<>( springArtifacts ); + Collections.sort( artifacts, new Comparator() + { + @Override + public int compare( ArtifactMetadata o1, ArtifactMetadata o2 ) + { + return o1.getId().compareTo( o2.getId() ); + } + } ); + + assertEquals( 3, artifacts.size() ); + + ArtifactMetadata artifactMetadata = artifacts.get( 0 ); + assertEquals( "plexus-spring-1.2-sources.jar", artifactMetadata.getId() ); + MavenArtifactFacet facet = (MavenArtifactFacet) artifactMetadata.getFacet( MavenArtifactFacet.FACET_ID ); + assertEquals( 0, facet.getBuildNumber() ); + assertNull( facet.getTimestamp() ); + assertEquals( "sources", facet.getClassifier() ); + assertEquals( "java-source", facet.getType() ); + + artifactMetadata = artifacts.get( 1 ); + assertEquals( "plexus-spring-1.2.jar", artifactMetadata.getId() ); + facet = (MavenArtifactFacet) artifactMetadata.getFacet( MavenArtifactFacet.FACET_ID ); + assertEquals( 0, facet.getBuildNumber() ); + assertNull( facet.getTimestamp() ); + assertNull( facet.getClassifier() ); + assertEquals( "jar", facet.getType() ); + + artifactMetadata = artifacts.get( 2 ); + assertEquals( "plexus-spring-1.2.pom", artifactMetadata.getId() ); + facet = (MavenArtifactFacet) artifactMetadata.getFacet( MavenArtifactFacet.FACET_ID ); + assertEquals( 0, facet.getBuildNumber() ); + assertNull( facet.getTimestamp() ); + assertNull( facet.getClassifier() ); + assertEquals( "pom", facet.getType() ); + } + + @Test + public void testGetArtifactMetadataSnapshots() + throws Exception + { + Collection testArtifacts = storage.readArtifactsMetadata( + new ReadMetadataRequest( TEST_REPO_ID, "com.example.test", "test-artifact", "1.0-SNAPSHOT", ALL ) ); + List artifacts = new ArrayList<>( testArtifacts ); + Collections.sort( artifacts, new Comparator() + { + @Override + public int compare( ArtifactMetadata o1, ArtifactMetadata o2 ) + { + return o1.getId().compareTo( o2.getId() ); + } + } ); + + assertEquals( 6, artifacts.size() ); + + ArtifactMetadata artifactMetadata = artifacts.get( 0 ); + assertEquals( "test-artifact-1.0-20100308.230825-1.jar", artifactMetadata.getId() ); + MavenArtifactFacet facet = (MavenArtifactFacet) artifactMetadata.getFacet( MavenArtifactFacet.FACET_ID ); + assertEquals( 1, facet.getBuildNumber() ); + assertEquals( "20100308.230825", facet.getTimestamp() ); + assertNull( facet.getClassifier() ); + assertEquals( "jar", facet.getType() ); + + artifactMetadata = artifacts.get( 1 ); + assertEquals( "test-artifact-1.0-20100308.230825-1.pom", artifactMetadata.getId() ); + facet = (MavenArtifactFacet) artifactMetadata.getFacet( MavenArtifactFacet.FACET_ID ); + assertEquals( 1, facet.getBuildNumber() ); + assertEquals( "20100308.230825", facet.getTimestamp() ); + assertNull( facet.getClassifier() ); + assertEquals( "pom", facet.getType() ); + + artifactMetadata = artifacts.get( 2 ); + assertEquals( "test-artifact-1.0-20100310.014828-2-javadoc.jar", artifactMetadata.getId() ); + facet = (MavenArtifactFacet) artifactMetadata.getFacet( MavenArtifactFacet.FACET_ID ); + assertEquals( 2, facet.getBuildNumber() ); + assertEquals( "20100310.014828", facet.getTimestamp() ); + assertEquals( "javadoc", facet.getClassifier() ); + assertEquals( "javadoc", facet.getType() ); + + artifactMetadata = artifacts.get( 3 ); + assertEquals( "test-artifact-1.0-20100310.014828-2-sources.jar", artifactMetadata.getId() ); + facet = (MavenArtifactFacet) artifactMetadata.getFacet( MavenArtifactFacet.FACET_ID ); + assertEquals( 2, facet.getBuildNumber() ); + assertEquals( "20100310.014828", facet.getTimestamp() ); + assertEquals( "sources", facet.getClassifier() ); + assertEquals( "java-source", facet.getType() ); + + artifactMetadata = artifacts.get( 4 ); + assertEquals( "test-artifact-1.0-20100310.014828-2.jar", artifactMetadata.getId() ); + facet = (MavenArtifactFacet) artifactMetadata.getFacet( MavenArtifactFacet.FACET_ID ); + assertEquals( 2, facet.getBuildNumber() ); + assertEquals( "20100310.014828", facet.getTimestamp() ); + assertNull( facet.getClassifier() ); + assertEquals( "jar", facet.getType() ); + + artifactMetadata = artifacts.get( 5 ); + assertEquals( "test-artifact-1.0-20100310.014828-2.pom", artifactMetadata.getId() ); + facet = (MavenArtifactFacet) artifactMetadata.getFacet( MavenArtifactFacet.FACET_ID ); + assertEquals( 2, facet.getBuildNumber() ); + assertEquals( "20100310.014828", facet.getTimestamp() ); + assertNull( facet.getClassifier() ); + assertEquals( "pom", facet.getType() ); + } + + @Test + public void testGetArtifactMetadataSnapshotsMRM1859() + throws Exception + { + Path repoDir = Paths.get("target/test-repository/com/example/test/test-artifact/1.0-SNAPSHOT"); + URL url = Thread.currentThread().getContextClassLoader().getResource("resolver-status.properties"); + Path resFile = Paths.get(url.toURI()); + Path destFile = repoDir.resolve(resFile.getFileName()); + Files.copy(resFile, destFile, StandardCopyOption.REPLACE_EXISTING); + URL url2 = Thread.currentThread().getContextClassLoader().getResource("test01.properties"); + Path resFile2 = Paths.get(url2.toURI()); + Path destFile2 = repoDir.resolve(resFile2.getFileName()); + Files.copy(resFile2, destFile2, StandardCopyOption.REPLACE_EXISTING); + + try { + + + Collection testArtifacts = storage.readArtifactsMetadata( + new ReadMetadataRequest(TEST_REPO_ID, "com.example.test", "test-artifact", "1.0-SNAPSHOT", ALL)); + List artifacts = new ArrayList<>(testArtifacts); + Collections.sort(artifacts, new Comparator() { + @Override + public int compare(ArtifactMetadata o1, ArtifactMetadata o2) { + return o1.getId().compareTo(o2.getId()); + } + }); + + assertEquals(6, artifacts.size()); + + ArtifactMetadata artifactMetadata = artifacts.get(0); + assertEquals("test-artifact-1.0-20100308.230825-1.jar", artifactMetadata.getId()); + MavenArtifactFacet facet = (MavenArtifactFacet) artifactMetadata.getFacet(MavenArtifactFacet.FACET_ID); + assertEquals(1, facet.getBuildNumber()); + assertEquals("20100308.230825", facet.getTimestamp()); + assertNull(facet.getClassifier()); + assertEquals("jar", facet.getType()); + + artifactMetadata = artifacts.get(1); + assertEquals("test-artifact-1.0-20100308.230825-1.pom", artifactMetadata.getId()); + facet = (MavenArtifactFacet) artifactMetadata.getFacet(MavenArtifactFacet.FACET_ID); + assertEquals(1, facet.getBuildNumber()); + assertEquals("20100308.230825", facet.getTimestamp()); + assertNull(facet.getClassifier()); + assertEquals("pom", facet.getType()); + + artifactMetadata = artifacts.get(2); + assertEquals("test-artifact-1.0-20100310.014828-2-javadoc.jar", artifactMetadata.getId()); + facet = (MavenArtifactFacet) artifactMetadata.getFacet(MavenArtifactFacet.FACET_ID); + assertEquals(2, facet.getBuildNumber()); + assertEquals("20100310.014828", facet.getTimestamp()); + assertEquals("javadoc", facet.getClassifier()); + assertEquals("javadoc", facet.getType()); + + artifactMetadata = artifacts.get(3); + assertEquals("test-artifact-1.0-20100310.014828-2-sources.jar", artifactMetadata.getId()); + facet = (MavenArtifactFacet) artifactMetadata.getFacet(MavenArtifactFacet.FACET_ID); + assertEquals(2, facet.getBuildNumber()); + assertEquals("20100310.014828", facet.getTimestamp()); + assertEquals("sources", facet.getClassifier()); + assertEquals("java-source", facet.getType()); + + artifactMetadata = artifacts.get(4); + assertEquals("test-artifact-1.0-20100310.014828-2.jar", artifactMetadata.getId()); + facet = (MavenArtifactFacet) artifactMetadata.getFacet(MavenArtifactFacet.FACET_ID); + assertEquals(2, facet.getBuildNumber()); + assertEquals("20100310.014828", facet.getTimestamp()); + assertNull(facet.getClassifier()); + assertEquals("jar", facet.getType()); + + artifactMetadata = artifacts.get(5); + assertEquals("test-artifact-1.0-20100310.014828-2.pom", artifactMetadata.getId()); + facet = (MavenArtifactFacet) artifactMetadata.getFacet(MavenArtifactFacet.FACET_ID); + assertEquals(2, facet.getBuildNumber()); + assertEquals("20100310.014828", facet.getTimestamp()); + assertNull(facet.getClassifier()); + assertEquals("pom", facet.getType()); + + } finally { + Files.delete(destFile); + Files.delete(destFile2); + } + + } + + private void assertDependency( Dependency dependency, String groupId, String artifactId, String version ) + { + assertDependency( dependency, groupId, artifactId, version, "compile" ); + } + + private void assertDependency( Dependency dependency, String groupId, String artifactId, String version, + String scope ) + { + assertEquals( artifactId, dependency.getArtifactId() ); + assertEquals( "jar", dependency.getType() ); + assertEquals( version, dependency.getVersion() ); + assertEquals( groupId, dependency.getNamespace() ); + assertEquals( scope, dependency.getScope() ); + assertNull( dependency.getClassifier() ); + assertNull( dependency.getSystemPath() ); + } + + @Test + public void testGetProjectVersionMetadataForTimestampedSnapshot() + throws Exception + { + ProjectVersionMetadata metadata = storage.readProjectVersionMetadata( + new ReadMetadataRequest( TEST_REPO_ID, "org.apache", "apache", "5-SNAPSHOT" ) ); + MavenProjectFacet facet = MavenProjectFacet.class.cast( metadata.getFacet( MavenProjectFacet.FACET_ID ) ); + assertEquals( "pom", facet.getPackaging() ); + assertEquals( "http://www.apache.org/", metadata.getUrl() ); + assertNull( facet.getParent() ); + assertEquals( "org.apache", facet.getGroupId() ); + assertEquals( "apache", facet.getArtifactId() ); + assertNull( metadata.getCiManagement() ); + assertNotNull( metadata.getDescription() ); + // TODO: this would be better +// assertEquals( +// "The Apache Software Foundation provides support for the Apache community of open-source software projects. " + +// "The Apache projects are characterized by a collaborative, consensus based development process, an open " + +// "and pragmatic software license, and a desire to create high quality software that leads the way in its " + +// "field. We consider ourselves not simply a group of projects sharing a server, but rather a community of " + +// "developers and users.", metadata.getDescription() ); + assertEquals( "5-SNAPSHOT", metadata.getId() ); + assertNull( metadata.getIssueManagement() ); + checkApacheLicense( metadata ); + assertEquals( "The Apache Software Foundation", metadata.getName() ); + String path = "maven/pom/trunk/asf"; + assertEquals( ASF_SCM_CONN_BASE + path, metadata.getScm().getConnection() ); + assertEquals( ASF_SCM_DEV_CONN_BASE + path, metadata.getScm().getDeveloperConnection() ); + assertEquals( ASF_SCM_VIEWVC_BASE + path, metadata.getScm().getUrl() ); + checkOrganizationApache( metadata ); + assertEquals( 1, metadata.getMailingLists().size() ); + assertMailingList( metadata.getMailingLists().get( 0 ), "Apache Announce List", + "http://mail-archives.apache.org/mod_mbox/www-announce/", "announce@apache.org", + "announce-subscribe@apache.org", "announce-unsubscribe@apache.org", + Collections.emptyList(), true ); + assertEquals( Collections.emptyList(), metadata.getDependencies() ); + } + + @Test + public void testGetProjectVersionMetadataForTimestampedSnapshotMissingMetadata() + throws Exception + { + try + { + storage.readProjectVersionMetadata( + new ReadMetadataRequest( TEST_REPO_ID, "com.example.test", "missing-metadata", "1.0-SNAPSHOT" ) ); + fail( "Should not be found" ); + } + catch ( RepositoryStorageMetadataNotFoundException e ) + { + assertEquals( "missing-pom", e.getId() ); + } + } + + @Test + public void testGetProjectVersionMetadataForTimestampedSnapshotMalformedMetadata() + throws Exception + { + try + { + storage.readProjectVersionMetadata( + new ReadMetadataRequest( TEST_REPO_ID, "com.example.test", "malformed-metadata", "1.0-SNAPSHOT" ) ); + fail( "Should not be found" ); + } + catch ( RepositoryStorageMetadataNotFoundException e ) + { + assertEquals( "missing-pom", e.getId() ); + } + } + + @Test + public void testGetProjectVersionMetadataForTimestampedSnapshotIncompleteMetadata() + throws Exception + { + try + { + storage.readProjectVersionMetadata( + new ReadMetadataRequest( TEST_REPO_ID, "com.example.test", "incomplete-metadata", "1.0-SNAPSHOT" ) ); + fail( "Should not be found" ); + } + catch ( RepositoryStorageMetadataNotFoundException e ) + { + assertEquals( "missing-pom", e.getId() ); + } + } + + @Test + public void testGetProjectVersionMetadataForInvalidPom() + throws Exception + { + try + { + storage.readProjectVersionMetadata( + new ReadMetadataRequest( TEST_REPO_ID, "com.example.test", "invalid-pom", "1.0" ) ); + fail( "Should have received an exception due to invalid POM" ); + } + catch ( RepositoryStorageMetadataInvalidException e ) + { + assertEquals( "invalid-pom", e.getId() ); + } + } + + @Test + public void testGetProjectVersionMetadataForMislocatedPom() + throws Exception + { + try + { + storage.readProjectVersionMetadata( + new ReadMetadataRequest( TEST_REPO_ID, "com.example.test", "mislocated-pom", "1.0" ) ); + fail( "Should have received an exception due to mislocated POM" ); + } + catch ( RepositoryStorageMetadataInvalidException e ) + { + assertEquals( "mislocated-pom", e.getId() ); + } + } + + @Test + public void testGetProjectVersionMetadataForMissingPom() + throws Exception + { + try + { + storage.readProjectVersionMetadata( + new ReadMetadataRequest( TEST_REPO_ID, "com.example.test", "missing-pom", "1.0" ) ); + fail( "Should not be found" ); + } + catch ( RepositoryStorageMetadataNotFoundException e ) + { + assertEquals( "missing-pom", e.getId() ); + } + } + + @Test + public void testGetRootNamespaces() + throws Exception + { + assertEquals( Arrays.asList( "com", "org"), storage.listRootNamespaces( TEST_REPO_ID, ALL ) ); + } + + @Test + public void testGetNamespaces() + throws Exception + { + assertEquals( Arrays.asList( "example" ), storage.listNamespaces( TEST_REPO_ID, "com", ALL ) ); + assertEquals( Arrays.asList( "test" ), storage.listNamespaces( TEST_REPO_ID, "com.example", ALL ) ); + assertEquals( Collections.emptyList(), + storage.listNamespaces( TEST_REPO_ID, "com.example.test", ALL ) ); + + assertEquals( Arrays.asList( "apache", "codehaus" ), storage.listNamespaces( TEST_REPO_ID, "org", ALL ) ); + assertEquals( Arrays.asList( "archiva", "maven" ), storage.listNamespaces( TEST_REPO_ID, "org.apache", ALL ) ); + assertEquals( Collections.emptyList(), + storage.listNamespaces( TEST_REPO_ID, "org.apache.archiva", ALL ) ); + assertEquals( Arrays.asList( "plugins", "shared" ), + storage.listNamespaces( TEST_REPO_ID, "org.apache.maven", ALL ) ); + assertEquals( Collections.emptyList(), + storage.listNamespaces( TEST_REPO_ID, "org.apache.maven.plugins", ALL ) ); + assertEquals( Collections.emptyList(), + storage.listNamespaces( TEST_REPO_ID, "org.apache.maven.shared", ALL ) ); + + assertEquals( Arrays.asList( "plexus" ), storage.listNamespaces( TEST_REPO_ID, "org.codehaus", ALL ) ); + assertEquals( Collections.emptyList(), + storage.listNamespaces( TEST_REPO_ID, "org.codehaus.plexus", ALL ) ); + } + + @Test + public void testGetProjects() + throws Exception + { + assertEquals( Collections.emptyList(), storage.listProjects( TEST_REPO_ID, "com", ALL ) ); + assertEquals( Collections.emptyList(), storage.listProjects( TEST_REPO_ID, "com.example", ALL ) ); + assertEquals( Arrays.asList( "incomplete-metadata", "invalid-pom", "malformed-metadata", "mislocated-pom", + "missing-metadata", "missing-parent", "test-artifact" ), + storage.listProjects( TEST_REPO_ID, "com.example.test", ALL ) ); + + assertEquals( Collections.emptyList(), storage.listProjects( TEST_REPO_ID, "org", ALL ) ); + assertEquals( Arrays.asList( "apache" ), storage.listProjects( TEST_REPO_ID, "org.apache", ALL ) ); + assertEquals( Arrays.asList( "archiva", "archiva-base", "archiva-common", "archiva-modules", "archiva-parent" ), + storage.listProjects( TEST_REPO_ID, "org.apache.archiva", ALL ) ); + assertEquals( Arrays.asList( "maven-archiver", "maven-parent" ), + storage.listProjects( TEST_REPO_ID, "org.apache.maven", ALL ) ); + assertEquals( Collections.emptyList(), + storage.listProjects( TEST_REPO_ID, "org.apache.maven.plugins", ALL ) ); + assertEquals( Arrays.asList( "maven-downloader", "maven-shared-components" ), + storage.listProjects( TEST_REPO_ID, "org.apache.maven.shared", ALL ) ); + } + + @Test + public void testGetProjectVersions() + throws Exception + { + assertEquals( Arrays.asList( "1.0-SNAPSHOT" ), + storage.listProjectVersions( TEST_REPO_ID, "com.example.test", "incomplete-metadata", ALL ) ); + assertEquals( Arrays.asList( "1.0-SNAPSHOT" ), + storage.listProjectVersions( TEST_REPO_ID, "com.example.test", "malformed-metadata", ALL ) ); + assertEquals( Arrays.asList( "1.0-SNAPSHOT" ), + storage.listProjectVersions( TEST_REPO_ID, "com.example.test", "missing-metadata", ALL ) ); + assertEquals( Arrays.asList( "1.0" ), + storage.listProjectVersions( TEST_REPO_ID, "com.example.test", "invalid-pom", ALL ) ); + + assertEquals( Arrays.asList( "4", "5-SNAPSHOT", "7" ), + storage.listProjectVersions( TEST_REPO_ID, "org.apache", "apache", ALL ) ); + + assertEquals( Arrays.asList( "1.2.1", "1.2.2" ), + storage.listProjectVersions( TEST_REPO_ID, "org.apache.archiva", "archiva", ALL ) ); + assertEquals( Arrays.asList( "1.2.1" ), + storage.listProjectVersions( TEST_REPO_ID, "org.apache.archiva", "archiva-base", ALL ) ); + assertEquals( Arrays.asList( "1.2.1" ), + storage.listProjectVersions( TEST_REPO_ID, "org.apache.archiva", "archiva-common", ALL ) ); + assertEquals( Arrays.asList( "1.2.1" ), + storage.listProjectVersions( TEST_REPO_ID, "org.apache.archiva", "archiva-modules", ALL ) ); + assertEquals( Arrays.asList( "3" ), + storage.listProjectVersions( TEST_REPO_ID, "org.apache.archiva", "archiva-parent", ALL ) ); + + assertEquals( Collections.emptyList(), + storage.listProjectVersions( TEST_REPO_ID, "org.apache.maven.shared", "maven-downloader", ALL ) ); + } + + @Test + public void testGetArtifacts() + throws Exception + { + List artifacts = new ArrayList<>( storage.readArtifactsMetadata( + new ReadMetadataRequest( TEST_REPO_ID, "org.codehaus.plexus", "plexus-spring", "1.2", ALL ) ) ); + assertEquals( 3, artifacts.size() ); + Collections.sort( artifacts, new Comparator() + { + @Override + public int compare( ArtifactMetadata o1, ArtifactMetadata o2 ) + { + return o1.getId().compareTo( o2.getId() ); + } + } ); + + assertArtifact( artifacts.get( 0 ), "plexus-spring-1.2-sources.jar", 0, EMPTY_SHA1, EMPTY_MD5 ); + assertArtifact( artifacts.get( 1 ), "plexus-spring-1.2.jar", 0, EMPTY_SHA1, EMPTY_MD5 ); + assertArtifact( artifacts.get( 2 ), "plexus-spring-1.2.pom", 7407, "96b14cf880e384b2d15e8193c57b65c5420ca4c5", + "f83aa25f016212a551a4b2249985effc" ); + } + + @Test + public void testGetArtifactsFiltered() + throws Exception + { + ExcludesFilter filter = + new ExcludesFilter( Collections.singletonList( "plexus-spring-1.2.pom" ) ); + List artifacts = new ArrayList<>( storage.readArtifactsMetadata( + new ReadMetadataRequest( TEST_REPO_ID, "org.codehaus.plexus", "plexus-spring", "1.2", filter ) ) ); + assertEquals( 2, artifacts.size() ); + Collections.sort( artifacts, new Comparator() + { + @Override + public int compare( ArtifactMetadata o1, ArtifactMetadata o2 ) + { + return o1.getId().compareTo( o2.getId() ); + } + } ); + + assertArtifact( artifacts.get( 0 ), "plexus-spring-1.2-sources.jar", 0, EMPTY_SHA1, EMPTY_MD5 ); + assertArtifact( artifacts.get( 1 ), "plexus-spring-1.2.jar", 0, EMPTY_SHA1, EMPTY_MD5 ); + } + + @Test + public void testGetArtifactsTimestampedSnapshots() + throws Exception + { + List artifacts = new ArrayList( storage.readArtifactsMetadata( + new ReadMetadataRequest( TEST_REPO_ID, "com.example.test", "missing-metadata", "1.0-SNAPSHOT", ALL ) ) ); + assertEquals( 1, artifacts.size() ); + + ArtifactMetadata artifact = artifacts.get( 0 ); + assertEquals( "missing-metadata-1.0-20091101.112233-1.pom", artifact.getId() ); + assertEquals( "com.example.test", artifact.getNamespace() ); + assertEquals( "missing-metadata", artifact.getProject() ); + assertEquals( "1.0-20091101.112233-1", artifact.getVersion() ); + assertEquals( TEST_REPO_ID, artifact.getRepositoryId() ); + } + + private void assertArtifact( ArtifactMetadata artifact, String id, int size, String sha1, String md5 ) + { + assertEquals( id, artifact.getId() ); + assertEquals( md5, artifact.getMd5() ); + assertEquals( sha1, artifact.getSha1() ); + assertEquals( size, artifact.getSize() ); + assertEquals( "org.codehaus.plexus", artifact.getNamespace() ); + assertEquals( "plexus-spring", artifact.getProject() ); + assertEquals( "1.2", artifact.getVersion() ); + assertEquals( TEST_REPO_ID, artifact.getRepositoryId() ); + } + + private void assertMailingList( MailingList mailingList, String name, String archive, String post, String subscribe, + String unsubscribe, List otherArchives, boolean allowPost ) + { + assertEquals( archive, mailingList.getMainArchiveUrl() ); + if ( allowPost ) + { + assertEquals( post, mailingList.getPostAddress() ); + } + else + { + assertNull( mailingList.getPostAddress() ); + } + assertEquals( subscribe, mailingList.getSubscribeAddress() ); + assertEquals( unsubscribe, mailingList.getUnsubscribeAddress() ); + assertEquals( name, mailingList.getName() ); + assertEquals( otherArchives, mailingList.getOtherArchives() ); + } + + private void assertMailingList( String prefix, MailingList mailingList, String name, boolean allowPost, + String nabbleUrl ) + { + List otherArchives = new ArrayList<>(); + otherArchives.add( "http://www.mail-archive.com/" + prefix + "@archiva.apache.org" ); + if ( nabbleUrl != null ) + { + otherArchives.add( nabbleUrl ); + } + otherArchives.add( "http://markmail.org/list/org.apache.archiva." + prefix ); + assertMailingList( mailingList, name, "http://mail-archives.apache.org/mod_mbox/archiva-" + prefix + "/", + prefix + "@archiva.apache.org", prefix + "-subscribe@archiva.apache.org", + prefix + "-unsubscribe@archiva.apache.org", otherArchives, allowPost ); + } + + private void checkApacheLicense( ProjectVersionMetadata metadata ) + { + assertEquals( Arrays.asList( new License( "The Apache Software License, Version 2.0", + "http://www.apache.org/licenses/LICENSE-2.0.txt" ) ), + metadata.getLicenses() ); + } + + private void checkOrganizationApache( ProjectVersionMetadata metadata ) + { + assertEquals( "The Apache Software Foundation", metadata.getOrganization().getName() ); + assertEquals( "http://www.apache.org/", metadata.getOrganization().getUrl() ); + } + + private void deleteTestArtifactWithParent( List pathsToBeDeleted ) + throws IOException + { + for ( String path : pathsToBeDeleted ) + { + Path dir = Paths.get( org.apache.archiva.common.utils.FileUtils.getBasedir(), path ); + org.apache.archiva.common.utils.FileUtils.deleteDirectory( dir ); + + assertFalse( Files.exists(dir) ); + } + Path dest = Paths.get( org.apache.archiva.common.utils.FileUtils.getBasedir(), "target/test-repository/com/example/test/test-artifact-module-a" ); + Path parentPom = + Paths.get( org.apache.archiva.common.utils.FileUtils.getBasedir(), "target/test-repository/com/example/test/test-artifact-parent" ); + Path rootPom = Paths.get( org.apache.archiva.common.utils.FileUtils.getBasedir(), "target/test-repository/com/example/test/test-artifact-root" ); + + org.apache.archiva.common.utils.FileUtils.deleteDirectory( dest ); + org.apache.archiva.common.utils.FileUtils.deleteDirectory( parentPom ); + org.apache.archiva.common.utils.FileUtils.deleteDirectory( rootPom ); + + assertFalse( Files.exists(dest) ); + assertFalse( Files.exists(parentPom) ); + assertFalse( Files.exists(rootPom) ); + } + + private Path copyTestArtifactWithParent( String srcPath, String destPath ) + throws IOException + { + Path src = Paths.get( org.apache.archiva.common.utils.FileUtils.getBasedir(), srcPath ); + Path dest = Paths.get( org.apache.archiva.common.utils.FileUtils.getBasedir(), destPath ); + + FileUtils.copyDirectory( src.toFile(), dest.toFile() ); + assertTrue( Files.exists(dest) ); + return dest; + } + +} diff --git a/archiva-modules/archiva-maven/archiva-maven-repository/src/test/java/org/apache/archiva/maven/repository/metadata/storage/MavenRepositoryMetadataReaderTest.java b/archiva-modules/archiva-maven/archiva-maven-repository/src/test/java/org/apache/archiva/maven/repository/metadata/storage/MavenRepositoryMetadataReaderTest.java new file mode 100644 index 000000000..90b5228ec --- /dev/null +++ b/archiva-modules/archiva-maven/archiva-maven-repository/src/test/java/org/apache/archiva/maven/repository/metadata/storage/MavenRepositoryMetadataReaderTest.java @@ -0,0 +1,130 @@ +package org.apache.archiva.maven.repository.metadata.storage; + +/* + * 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.maven.metadata.MavenMetadataReader; +import org.apache.archiva.model.ArchivaRepositoryMetadata; +import org.apache.archiva.model.Plugin; +import org.apache.archiva.repository.metadata.RepositoryMetadataException; +import org.apache.archiva.test.utils.ArchivaBlockJUnit4ClassRunner; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; + +import java.nio.file.Path; +import java.nio.file.Paths; +import java.util.Arrays; + +/** + * RepositoryMetadataReaderTest + * + * + */ +@RunWith( ArchivaBlockJUnit4ClassRunner.class ) +public class MavenRepositoryMetadataReaderTest + extends TestCase +{ + private Path defaultRepoDir; + + @Test + public void testGroupMetadata() + throws RepositoryMetadataException + { + Path metadataFile = defaultRepoDir.resolve( "org/apache/maven/plugins/maven-metadata.xml" ); + + MavenMetadataReader metadataReader = new MavenMetadataReader( ); + ArchivaRepositoryMetadata metadata = metadataReader.read( metadataFile ); + + assertNotNull( metadata ); + assertEquals( "org.apache.maven.plugins", metadata.getGroupId() ); + assertNull( metadata.getArtifactId() ); + assertNull( metadata.getReleasedVersion() ); + assertNull( metadata.getLatestVersion() ); + assertTrue( metadata.getAvailableVersions().isEmpty() ); + assertNull( metadata.getSnapshotVersion() ); + assertNull( metadata.getLastUpdated() ); + + Plugin cleanPlugin = new Plugin(); + cleanPlugin.setPrefix( "clean" ); + cleanPlugin.setArtifactId( "maven-clean-plugin" ); + cleanPlugin.setName( "Maven Clean Plugin" ); + + Plugin compilerPlugin = new Plugin(); + compilerPlugin.setPrefix( "compiler" ); + compilerPlugin.setArtifactId( "maven-compiler-plugin" ); + compilerPlugin.setName( "Maven Compiler Plugin" ); + + Plugin surefirePlugin = new Plugin(); + surefirePlugin.setPrefix( "surefire" ); + surefirePlugin.setArtifactId( "maven-surefire-plugin" ); + surefirePlugin.setName( "Maven Surefire Plugin" ); + + assertEquals( Arrays.asList( cleanPlugin, compilerPlugin, surefirePlugin ), metadata.getPlugins() ); + } + + @Test + public void testProjectMetadata() + throws RepositoryMetadataException + { + Path metadataFile = defaultRepoDir.resolve( "org/apache/maven/shared/maven-downloader/maven-metadata.xml" ); + + MavenMetadataReader metadataReader = new MavenMetadataReader( ); + ArchivaRepositoryMetadata metadata = metadataReader.read( metadataFile ); + + assertNotNull( metadata ); + assertEquals( "org.apache.maven.shared", metadata.getGroupId() ); + assertEquals( "maven-downloader", metadata.getArtifactId() ); + assertEquals( "1.1", metadata.getReleasedVersion() ); + assertNull( metadata.getLatestVersion() ); + assertEquals( Arrays.asList( "1.0", "1.1" ), metadata.getAvailableVersions() ); + assertNull( metadata.getSnapshotVersion() ); + assertEquals( "20061212214311", metadata.getLastUpdated() ); + } + + @Test + public void testProjectVersionMetadata() + throws RepositoryMetadataException + { + Path metadataFile = defaultRepoDir.resolve( "org/apache/apache/5-SNAPSHOT/maven-metadata.xml" ); + + MavenMetadataReader metadataReader = new MavenMetadataReader( ); + ArchivaRepositoryMetadata metadata = metadataReader.read(metadataFile ); + + assertNotNull( metadata ); + assertEquals( "org.apache", metadata.getGroupId() ); + assertEquals( "apache", metadata.getArtifactId() ); + assertNull( metadata.getReleasedVersion() ); + assertNull( metadata.getLatestVersion() ); + assertTrue( metadata.getAvailableVersions().isEmpty() ); + assertNotNull( metadata.getSnapshotVersion() ); + assertEquals( "20080801.151215", metadata.getSnapshotVersion().getTimestamp() ); + assertEquals( 1, metadata.getSnapshotVersion().getBuildNumber() ); + assertEquals( "20080801151215", metadata.getLastUpdated() ); + } + + @Before + @Override + public void setUp() + throws Exception + { + super.setUp(); + defaultRepoDir = Paths.get("target/test-repository"); + } +} \ No newline at end of file diff --git a/archiva-modules/archiva-maven/archiva-maven-repository/src/test/java/org/apache/archiva/maven/repository/metadata/storage/MockWagon.java b/archiva-modules/archiva-maven/archiva-maven-repository/src/test/java/org/apache/archiva/maven/repository/metadata/storage/MockWagon.java new file mode 100644 index 000000000..4e32786c6 --- /dev/null +++ b/archiva-modules/archiva-maven/archiva-maven-repository/src/test/java/org/apache/archiva/maven/repository/metadata/storage/MockWagon.java @@ -0,0 +1,247 @@ +package org.apache.archiva.maven.repository.metadata.storage; + +/* + * 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.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 +{ + @Override + public void get( String s, File file ) + throws TransferFailedException, ResourceDoesNotExistException, AuthorizationException + { + String sourceFile = getBasedir() + "/src/test/resources/" + s; + + try + { + FileUtils.copyFile( new File( sourceFile ), file ); + assert( file.exists() ); + } + catch( IOException e ) + { + throw new ResourceDoesNotExistException( e.getMessage() ); + } + } + + @Override + public boolean getIfNewer( String s, File file, long l ) + throws TransferFailedException, ResourceDoesNotExistException, AuthorizationException + { + return false; + } + + @Override + public void put( File file, String s ) + throws TransferFailedException, ResourceDoesNotExistException, AuthorizationException + { + + } + + @Override + public void putDirectory( File file, String s ) + throws TransferFailedException, ResourceDoesNotExistException, AuthorizationException + { + + } + + @Override + public boolean resourceExists( String s ) + throws TransferFailedException, AuthorizationException + { + return false; + } + + @Override + public List getFileList( String s ) + throws TransferFailedException, ResourceDoesNotExistException, AuthorizationException + { + return null; + } + + @Override + public boolean supportsDirectoryCopy() + { + return false; + } + + @Override + public Repository getRepository() + { + return null; + } + + @Override + public void connect( Repository repository ) + throws ConnectionException, AuthenticationException + { + + } + + @Override + public void connect( Repository repository, ProxyInfo proxyInfo ) + throws ConnectionException, AuthenticationException + { + + } + + @Override + public void connect( Repository repository, ProxyInfoProvider proxyInfoProvider ) + throws ConnectionException, AuthenticationException + { + + } + + @Override + public void connect( Repository repository, AuthenticationInfo authenticationInfo ) + throws ConnectionException, AuthenticationException + { + + } + + @Override + public void connect( Repository repository, AuthenticationInfo authenticationInfo, ProxyInfo proxyInfo ) + throws ConnectionException, AuthenticationException + { + + } + + @Override + public void connect( Repository repository, AuthenticationInfo authenticationInfo, + ProxyInfoProvider proxyInfoProvider ) + throws ConnectionException, AuthenticationException + { + + } + + @Deprecated + @Override + public void openConnection() + throws ConnectionException, AuthenticationException + { + + } + + @Override + public void disconnect() + throws ConnectionException + { + + } + + @Override + public void setTimeout( int i ) + { + + } + + @Override + public int getTimeout() + { + return 0; + } + + @Override + public void setReadTimeout( int timeoutValue ) + { + + } + + @Override + public int getReadTimeout() + { + return 0; + } + + @Override + public void addSessionListener( SessionListener sessionListener ) + { + + } + + @Override + public void removeSessionListener( SessionListener sessionListener ) + { + + } + + @Override + public boolean hasSessionListener( SessionListener sessionListener ) + { + return false; + } + + @Override + public void addTransferListener( TransferListener transferListener ) + { + + } + + @Override + public void removeTransferListener( TransferListener transferListener ) + { + + } + + @Override + public boolean hasTransferListener( TransferListener transferListener ) + { + return false; + } + + @Override + public boolean isInteractive() + { + return false; + } + + @Override + 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/archiva-maven/archiva-maven-repository/src/test/java/org/apache/archiva/maven/repository/metadata/storage/mock/MockConfiguration.java b/archiva-modules/archiva-maven/archiva-maven-repository/src/test/java/org/apache/archiva/maven/repository/metadata/storage/mock/MockConfiguration.java new file mode 100644 index 000000000..a9dd1e419 --- /dev/null +++ b/archiva-modules/archiva-maven/archiva-maven-repository/src/test/java/org/apache/archiva/maven/repository/metadata/storage/mock/MockConfiguration.java @@ -0,0 +1,210 @@ +package org.apache.archiva.maven.repository.metadata.storage.mock; + +/* + * 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.components.registry.Registry; +import org.apache.archiva.components.registry.RegistryException; +import org.apache.archiva.components.registry.RegistryListener; +import org.apache.archiva.configuration.ArchivaConfiguration; +import org.apache.archiva.configuration.ArchivaRuntimeConfiguration; +import org.apache.archiva.configuration.Configuration; +import org.apache.archiva.configuration.ConfigurationListener; +import org.apache.archiva.configuration.FileType; +import org.apache.archiva.configuration.IndeterminateConfigurationException; +import org.apache.archiva.configuration.RepositoryScanningConfiguration; +import org.apache.commons.lang3.StringUtils; +import org.easymock.IMocksControl; +import org.springframework.stereotype.Service; + +import java.nio.file.Path; +import java.nio.file.Paths; +import java.util.ArrayList; +import java.util.HashSet; +import java.util.List; +import java.util.Locale; +import java.util.Set; + +import static org.easymock.EasyMock.createNiceControl; + +/** + * MockConfiguration + * + * + */ +@Service("archivaConfiguration#mock") +public class MockConfiguration + implements ArchivaConfiguration +{ + + private Configuration configuration = new Configuration(); + + private Set registryListeners = new HashSet(); + private Set configListeners = new HashSet(); + + private IMocksControl registryControl; + + private Registry registryMock; + + public MockConfiguration() + { + registryControl = createNiceControl(); + registryMock = registryControl.createMock( Registry.class ); + configuration.setArchivaRuntimeConfiguration(new ArchivaRuntimeConfiguration()); + configuration.getArchivaRuntimeConfiguration().addChecksumType("sha1"); + configuration.getArchivaRuntimeConfiguration().addChecksumType("sha256"); + configuration.getArchivaRuntimeConfiguration().addChecksumType("md5"); + RepositoryScanningConfiguration rpsc = new RepositoryScanningConfiguration( ); + FileType ft = new FileType( ); + ft.setId( "artifacts" ); + ArrayList plist = new ArrayList<>( ); + plist.add( "**/*.jar" ); + plist.add( "**/*.pom" ); + plist.add( "**/*.war" ); + ft.setPatterns( plist ); + rpsc.addFileType( ft ); + ArrayList ftList = new ArrayList<>( ); + ftList.add( ft ); + rpsc.setFileTypes( ftList ); + configuration.setRepositoryScanning( rpsc ); + } + + @Override + public void addChangeListener( RegistryListener listener ) + { + registryListeners.add( listener ); + } + + @Override + public void removeChangeListener( RegistryListener listener ) + { + registryListeners.remove( listener ); + } + + @Override + public Configuration getConfiguration() + { + return configuration; + } + + @Override + public void save( Configuration configuration ) + throws RegistryException + { + /* do nothing */ + } + + @Override + public void save( Configuration configuration, String eventTag ) throws RegistryException, IndeterminateConfigurationException + { + // do nothing + } + + public void triggerChange( String name, String value ) + { + for(RegistryListener listener: registryListeners) + { + try + { + listener.afterConfigurationChange( registryMock, name, value ); + } + catch ( Exception e ) + { + e.printStackTrace(); + } + } + } + + @Override + public void addListener( ConfigurationListener listener ) + { + configListeners.add(listener); + } + + @Override + public void removeListener( ConfigurationListener listener ) + { + configListeners.remove( listener ); + } + + @Override + public boolean isDefaulted() + { + return false; + } + + @Override + public void reload() + { + // no op + } + + @Override + public Locale getDefaultLocale( ) + { + return Locale.getDefault(); + } + + @Override + public List getLanguagePriorities( ) + { + return Locale.LanguageRange.parse( "en,fr,de" ); + } + + @Override + public Path getAppServerBaseDir() { + if (System.getProperties().containsKey("appserver.base")) { + return Paths.get(System.getProperty("appserver.base")); + } else { + return Paths.get(""); + } + } + + + @Override + public Path getRepositoryBaseDir() { + return getDataDirectory().resolve("repositories"); + } + + @Override + public Path getRemoteRepositoryBaseDir() { + return getDataDirectory().resolve("remotes"); + } + + @Override + public Path getRepositoryGroupBaseDir() { + return getDataDirectory().resolve("groups"); + } + + @Override + public Path getDataDirectory() { + if (configuration!=null && StringUtils.isNotEmpty(configuration.getArchivaRuntimeConfiguration().getDataDirectory())) { + return Paths.get(configuration.getArchivaRuntimeConfiguration().getDataDirectory()); + } else { + return getAppServerBaseDir().resolve("data"); + } + } + + @Override + public Registry getRegistry( ) + { + return null; + } + + +} diff --git a/archiva-modules/archiva-maven/archiva-maven-repository/src/test/java/org/apache/archiva/maven/repository/mock/ArchivaIndexManagerMock.java b/archiva-modules/archiva-maven/archiva-maven-repository/src/test/java/org/apache/archiva/maven/repository/mock/ArchivaIndexManagerMock.java new file mode 100644 index 000000000..0fadd50b3 --- /dev/null +++ b/archiva-modules/archiva-maven/archiva-maven-repository/src/test/java/org/apache/archiva/maven/repository/mock/ArchivaIndexManagerMock.java @@ -0,0 +1,826 @@ +package org.apache.archiva.maven.repository.mock; + +/* + * 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.filelock.DefaultFileLockManager; +import org.apache.archiva.common.utils.FileUtils; +import org.apache.archiva.common.utils.PathUtil; +import org.apache.archiva.configuration.ArchivaConfiguration; +import org.apache.archiva.indexer.ArchivaIndexManager; +import org.apache.archiva.indexer.ArchivaIndexingContext; +import org.apache.archiva.indexer.IndexCreationFailedException; +import org.apache.archiva.indexer.IndexUpdateFailedException; +import org.apache.archiva.indexer.UnsupportedBaseContextException; +import org.apache.archiva.proxy.ProxyRegistry; +import org.apache.archiva.maven.common.proxy.WagonFactory; +import org.apache.archiva.maven.common.proxy.WagonFactoryException; +import org.apache.archiva.maven.common.proxy.WagonFactoryRequest; +import org.apache.archiva.proxy.model.NetworkProxy; +import org.apache.archiva.repository.EditableRepository; +import org.apache.archiva.repository.ManagedRepository; +import org.apache.archiva.repository.RemoteRepository; +import org.apache.archiva.repository.Repository; +import org.apache.archiva.repository.RepositoryType; +import org.apache.archiva.repository.UnsupportedRepositoryTypeException; +import org.apache.archiva.repository.base.PasswordCredentials; +import org.apache.archiva.repository.features.IndexCreationFeature; +import org.apache.archiva.repository.features.RemoteIndexFeature; +import org.apache.archiva.repository.storage.StorageAsset; +import org.apache.archiva.repository.storage.fs.FilesystemAsset; +import org.apache.archiva.repository.storage.fs.FilesystemStorage; +import org.apache.commons.lang3.StringUtils; +import org.apache.maven.index.ArtifactContext; +import org.apache.maven.index.ArtifactContextProducer; +import org.apache.maven.index.DefaultScannerListener; +import org.apache.maven.index.Indexer; +import org.apache.maven.index.IndexerEngine; +import org.apache.maven.index.Scanner; +import org.apache.maven.index.ScanningRequest; +import org.apache.maven.index.ScanningResult; +import org.apache.maven.index.context.IndexCreator; +import org.apache.maven.index.context.IndexingContext; +import org.apache.maven.index.packer.IndexPacker; +import org.apache.maven.index.packer.IndexPackingRequest; +import org.apache.maven.index.updater.IndexUpdateRequest; +import org.apache.maven.index.updater.ResourceFetcher; +import org.apache.maven.index_shaded.lucene.index.IndexFormatTooOldException; +import org.apache.maven.wagon.ConnectionException; +import org.apache.maven.wagon.ResourceDoesNotExistException; +import org.apache.maven.wagon.StreamWagon; +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.TransferEvent; +import org.apache.maven.wagon.events.TransferListener; +import org.apache.maven.wagon.proxy.ProxyInfo; +import org.apache.maven.wagon.shared.http.AbstractHttpClientWagon; +import org.apache.maven.wagon.shared.http.HttpConfiguration; +import org.apache.maven.wagon.shared.http.HttpMethodConfiguration; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.stereotype.Service; + +import javax.inject.Inject; +import java.io.FileNotFoundException; +import java.io.IOException; +import java.io.InputStream; +import java.net.MalformedURLException; +import java.net.URI; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.util.Collection; +import java.util.List; +import java.util.Map; +import java.util.concurrent.ConcurrentSkipListSet; +import java.util.stream.Collectors; + +/** + * @author Martin Stockhammer + */ +@Service("archivaIndexManager#maven") +public class ArchivaIndexManagerMock implements ArchivaIndexManager { + private static final Logger log = LoggerFactory.getLogger( ArchivaIndexManagerMock.class ); + + @Inject + private Indexer indexer; + + @Inject + private IndexerEngine indexerEngine; + + @Inject + private List indexCreators; + + @Inject + private IndexPacker indexPacker; + + @Inject + private Scanner scanner; + + @Inject + private ArchivaConfiguration archivaConfiguration; + + @Inject + private WagonFactory wagonFactory; + + @Inject + private ArtifactContextProducer artifactContextProducer; + + @Inject + private ProxyRegistry proxyRegistry; + + private ConcurrentSkipListSet activeContexts = new ConcurrentSkipListSet<>( ); + + private static final int WAIT_TIME = 100; + private static final int MAX_WAIT = 10; + + + public static IndexingContext getMvnContext(ArchivaIndexingContext context ) throws UnsupportedBaseContextException + { + if ( !context.supports( IndexingContext.class ) ) + { + log.error( "The provided archiva index context does not support the maven IndexingContext" ); + throw new UnsupportedBaseContextException( "The context does not support the Maven IndexingContext" ); + } + return context.getBaseContext( IndexingContext.class ); + } + + private Path getIndexPath( ArchivaIndexingContext ctx ) + { + return ctx.getPath( ).getFilePath(); + } + + @FunctionalInterface + interface IndexUpdateConsumer + { + + void accept( IndexingContext indexingContext ) throws IndexUpdateFailedException; + } + + /* + * This method is used to do some actions around the update execution code. And to make sure, that no other + * method is running on the same index. + */ + private void executeUpdateFunction( ArchivaIndexingContext context, IndexUpdateConsumer function ) throws IndexUpdateFailedException + { + IndexingContext indexingContext = null; + try + { + indexingContext = getMvnContext( context ); + } + catch ( UnsupportedBaseContextException e ) + { + throw new IndexUpdateFailedException( "Maven index is not supported by this context", e ); + } + final Path ctxPath = getIndexPath( context ); + int loop = MAX_WAIT; + boolean active = false; + while ( loop-- > 0 && !active ) + { + active = activeContexts.add( ctxPath ); + try + { + Thread.currentThread( ).sleep( WAIT_TIME ); + } + catch ( InterruptedException e ) + { + // Ignore this + } + } + if ( active ) + { + try + { + function.accept( indexingContext ); + } + finally + { + activeContexts.remove( ctxPath ); + } + } + else + { + throw new IndexUpdateFailedException( "Timeout while waiting for index release on context " + context.getId( ) ); + } + } + + @Override + public void pack( final ArchivaIndexingContext context ) throws IndexUpdateFailedException + { + executeUpdateFunction( context, indexingContext -> { + try + { + IndexPackingRequest request = new IndexPackingRequest( indexingContext, + indexingContext.acquireIndexSearcher( ).getIndexReader( ), + indexingContext.getIndexDirectoryFile( ) ); + indexPacker.packIndex( request ); + indexingContext.updateTimestamp( true ); + } + catch ( IOException e ) + { + log.error( "IOException while packing index of context " + context.getId( ) + ( StringUtils.isNotEmpty( e.getMessage( ) ) ? ": " + e.getMessage( ) : "" ) ); + throw new IndexUpdateFailedException( "IOException during update of " + context.getId( ), e ); + } + } + ); + + } + + @Override + public void scan(final ArchivaIndexingContext context) throws IndexUpdateFailedException + { + executeUpdateFunction( context, indexingContext -> { + DefaultScannerListener listener = new DefaultScannerListener( indexingContext, indexerEngine, true, null ); + ScanningRequest request = new ScanningRequest( indexingContext, listener ); + ScanningResult result = scanner.scan( request ); + if ( result.hasExceptions( ) ) + { + log.error( "Exceptions occured during index scan of " + context.getId( ) ); + result.getExceptions( ).stream( ).map( e -> e.getMessage( ) ).distinct( ).limit( 5 ).forEach( + s -> log.error( "Message: " + s ) + ); + } + + } ); + } + + @Override + public void update(final ArchivaIndexingContext context, final boolean fullUpdate) throws IndexUpdateFailedException + { + log.info( "start download remote index for remote repository {}", context.getRepository( ).getId( ) ); + URI remoteUpdateUri; + if ( !( context.getRepository( ) instanceof RemoteRepository) || !(context.getRepository().supportsFeature(RemoteIndexFeature.class)) ) + { + throw new IndexUpdateFailedException( "The context is not associated to a remote repository with remote index " + context.getId( ) ); + } else { + RemoteIndexFeature rif = context.getRepository().getFeature(RemoteIndexFeature.class).get(); + remoteUpdateUri = context.getRepository().getLocation().resolve(rif.getIndexUri()); + } + final RemoteRepository remoteRepository = (RemoteRepository) context.getRepository( ); + + executeUpdateFunction( context, + indexingContext -> { + try + { + // create a temp directory to download files + Path tempIndexDirectory = Paths.get( indexingContext.getIndexDirectoryFile( ).getParent( ), ".tmpIndex" ); + Path indexCacheDirectory = Paths.get( indexingContext.getIndexDirectoryFile( ).getParent( ), ".indexCache" ); + Files.createDirectories( indexCacheDirectory ); + if ( Files.exists( tempIndexDirectory ) ) + { + org.apache.archiva.common.utils.FileUtils.deleteDirectory( tempIndexDirectory ); + } + Files.createDirectories( tempIndexDirectory ); + tempIndexDirectory.toFile( ).deleteOnExit( ); + String baseIndexUrl = indexingContext.getIndexUpdateUrl( ); + + String wagonProtocol = remoteUpdateUri.toURL( ).getProtocol( ); + + NetworkProxy networkProxy = null; + if ( remoteRepository.supportsFeature( RemoteIndexFeature.class ) ) + { + RemoteIndexFeature rif = remoteRepository.getFeature( RemoteIndexFeature.class ).get( ); + if ( StringUtils.isNotBlank( rif.getProxyId( ) ) ) + { + networkProxy = proxyRegistry.getNetworkProxy( rif.getProxyId( ) ); + if ( networkProxy == null ) + { + log.warn( + "your remote repository is configured to download remote index trought a proxy we cannot find id:{}", + rif.getProxyId( ) ); + } + } + + final StreamWagon wagon = (StreamWagon) wagonFactory.getWagon( + new WagonFactoryRequest( wagonProtocol, remoteRepository.getExtraHeaders( ) ).networkProxy( + networkProxy ) + ); + int readTimeout = (int) rif.getDownloadTimeout( ).toMillis( ) * 1000; + wagon.setReadTimeout( readTimeout ); + wagon.setTimeout( (int) remoteRepository.getTimeout( ).toMillis( ) * 1000 ); + + if ( wagon instanceof AbstractHttpClientWagon) + { + HttpConfiguration httpConfiguration = new HttpConfiguration( ); + HttpMethodConfiguration httpMethodConfiguration = new HttpMethodConfiguration( ); + httpMethodConfiguration.setUsePreemptive( true ); + httpMethodConfiguration.setReadTimeout( readTimeout ); + httpConfiguration.setGet( httpMethodConfiguration ); + AbstractHttpClientWagon.class.cast( wagon ).setHttpConfiguration( httpConfiguration ); + } + + wagon.addTransferListener( new DownloadListener( ) ); + ProxyInfo proxyInfo = null; + if ( networkProxy != null ) + { + proxyInfo = new ProxyInfo( ); + proxyInfo.setType( networkProxy.getProtocol( ) ); + proxyInfo.setHost( networkProxy.getHost( ) ); + proxyInfo.setPort( networkProxy.getPort( ) ); + proxyInfo.setUserName( networkProxy.getUsername( ) ); + proxyInfo.setPassword(new String(networkProxy.getPassword())); + } + AuthenticationInfo authenticationInfo = null; + if ( remoteRepository.getLoginCredentials( ) != null && ( remoteRepository.getLoginCredentials( ) instanceof PasswordCredentials) ) + { + PasswordCredentials creds = (PasswordCredentials) remoteRepository.getLoginCredentials( ); + authenticationInfo = new AuthenticationInfo( ); + authenticationInfo.setUserName( creds.getUsername( ) ); + authenticationInfo.setPassword( new String( creds.getPassword( ) ) ); + } + wagon.connect( new org.apache.maven.wagon.repository.Repository( remoteRepository.getId( ), baseIndexUrl ), authenticationInfo, + proxyInfo ); + + Path indexDirectory = indexingContext.getIndexDirectoryFile( ).toPath( ); + if ( !Files.exists( indexDirectory ) ) + { + Files.createDirectories( indexDirectory ); + } + + ResourceFetcher resourceFetcher = + new WagonResourceFetcher( log, tempIndexDirectory, wagon, remoteRepository ); + IndexUpdateRequest request = new IndexUpdateRequest( indexingContext, resourceFetcher ); + request.setForceFullUpdate( fullUpdate ); + request.setLocalIndexCacheDir( indexCacheDirectory.toFile( ) ); + + // indexUpdater.fetchAndUpdateIndex( request ); + + indexingContext.updateTimestamp( true ); + } + + } + catch ( AuthenticationException e ) + { + log.error( "Could not login to the remote proxy for updating index of {}", remoteRepository.getId( ), e ); + throw new IndexUpdateFailedException( "Login in to proxy failed while updating remote repository " + remoteRepository.getId( ), e ); + } + catch ( ConnectionException e ) + { + log.error( "Connection error during index update for remote repository {}", remoteRepository.getId( ), e ); + throw new IndexUpdateFailedException( "Connection error during index update for remote repository " + remoteRepository.getId( ), e ); + } + catch ( MalformedURLException e ) + { + log.error( "URL for remote index update of remote repository {} is not correct {}", remoteRepository.getId( ), remoteUpdateUri, e ); + throw new IndexUpdateFailedException( "URL for remote index update of repository is not correct " + remoteUpdateUri, e ); + } + catch ( IOException e ) + { + log.error( "IOException during index update of remote repository {}: {}", remoteRepository.getId( ), e.getMessage( ), e ); + throw new IndexUpdateFailedException( "IOException during index update of remote repository " + remoteRepository.getId( ) + + ( StringUtils.isNotEmpty( e.getMessage( ) ) ? ": " + e.getMessage( ) : "" ), e ); + } + catch ( WagonFactoryException e ) + { + log.error( "Wagon for remote index download of {} could not be created: {}", remoteRepository.getId( ), e.getMessage( ), e ); + throw new IndexUpdateFailedException( "Error while updating the remote index of " + remoteRepository.getId( ), e ); + } + } ); + + } + + @Override + public void addArtifactsToIndex( final ArchivaIndexingContext context, final Collection artifactReference ) throws IndexUpdateFailedException + { + final StorageAsset ctxUri = context.getPath(); + executeUpdateFunction(context, indexingContext -> { + Collection artifacts = artifactReference.stream().map(r -> artifactContextProducer.getArtifactContext(indexingContext, Paths.get(ctxUri.getFilePath().toUri().resolve(r)).toFile())).collect(Collectors.toList()); + try { + indexer.addArtifactsToIndex(artifacts, indexingContext); + } catch (IOException e) { + log.error("IOException while adding artifact {}", e.getMessage(), e); + throw new IndexUpdateFailedException("Error occured while adding artifact to index of "+context.getId() + + (StringUtils.isNotEmpty(e.getMessage()) ? ": "+e.getMessage() : "")); + } + }); + } + + @Override + public void removeArtifactsFromIndex( ArchivaIndexingContext context, Collection artifactReference ) throws IndexUpdateFailedException + { + final StorageAsset ctxUri = context.getPath(); + executeUpdateFunction(context, indexingContext -> { + Collection artifacts = artifactReference.stream().map(r -> artifactContextProducer.getArtifactContext(indexingContext, Paths.get(ctxUri.getFilePath().toUri().resolve(r)).toFile())).collect(Collectors.toList()); + try { + indexer.deleteArtifactsFromIndex(artifacts, indexingContext); + } catch (IOException e) { + log.error("IOException while removing artifact {}", e.getMessage(), e); + throw new IndexUpdateFailedException("Error occured while removing artifact from index of "+context.getId() + + (StringUtils.isNotEmpty(e.getMessage()) ? ": "+e.getMessage() : "")); + } + }); + + } + + @Override + public boolean supportsRepository( RepositoryType type ) + { + return type == RepositoryType.MAVEN; + } + + @Override + public ArchivaIndexingContext createContext( Repository repository ) throws IndexCreationFailedException + { + log.debug("Creating context for repo {}, type: {}", repository.getId(), repository.getType()); + if ( repository.getType( ) != RepositoryType.MAVEN ) + { + throw new UnsupportedRepositoryTypeException( repository.getType( ) ); + } + IndexingContext mvnCtx = null; + try + { + if ( repository instanceof RemoteRepository ) + { + mvnCtx = createRemoteContext( (RemoteRepository) repository ); + } + else if ( repository instanceof ManagedRepository ) + { + mvnCtx = createManagedContext( (ManagedRepository) repository ); + } + } + catch ( IOException e ) + { + log.error( "IOException during context creation " + e.getMessage( ), e ); + throw new IndexCreationFailedException( "Could not create index context for repository " + repository.getId( ) + + ( StringUtils.isNotEmpty( e.getMessage( ) ) ? ": " + e.getMessage( ) : "" ), e ); + } + MavenIndexContextMock context = null; + try { + context = new MavenIndexContextMock( repository, mvnCtx ); + } catch (IOException e) { + throw new IndexCreationFailedException(e); + } + + return context; + } + + @Override + public ArchivaIndexingContext reset(ArchivaIndexingContext context) throws IndexUpdateFailedException { + ArchivaIndexingContext ctx; + executeUpdateFunction(context, indexingContext -> { + try { + indexingContext.close(true); + } catch (IOException e) { + log.warn("Index close failed"); + } + try { + FileUtils.deleteDirectory(context.getPath().getFilePath()); + } catch (IOException e) { + throw new IndexUpdateFailedException("Could not delete index files"); + } + }); + try { + Repository repo = context.getRepository(); + ctx = createContext(context.getRepository()); + if (repo instanceof EditableRepository) { + ((EditableRepository)repo).setIndexingContext(ctx); + } + } catch (IndexCreationFailedException e) { + throw new IndexUpdateFailedException("Could not create index"); + } + return ctx; + } + + @Override + public ArchivaIndexingContext move(ArchivaIndexingContext context, Repository repo) throws IndexCreationFailedException { + if (context==null) { + return null; + } + if (context.supports(IndexingContext.class)) { + try { + StorageAsset newPath = getIndexPath(repo); + IndexingContext ctx = context.getBaseContext(IndexingContext.class); + Path oldPath = ctx.getIndexDirectoryFile().toPath(); + if (oldPath.equals(newPath)) { + // Nothing to do, if path does not change + return context; + } + if (!Files.exists(oldPath)) { + return createContext(repo); + } else if (context.isEmpty()) { + context.close(); + return createContext(repo); + } else { + context.close(false); + Files.move(oldPath, newPath.getFilePath()); + return createContext(repo); + } + } catch (IOException e) { + log.error("IOException while moving index directory {}", e.getMessage(), e); + throw new IndexCreationFailedException("Could not recreated the index.", e); + } catch (UnsupportedBaseContextException e) { + throw new IndexCreationFailedException("The given context, is not a maven context."); + } + } else { + throw new IndexCreationFailedException("Bad context type. This is not a maven context."); + } + } + + @Override + public void updateLocalIndexPath(Repository repo) { + if (repo.supportsFeature(IndexCreationFeature.class)) { + IndexCreationFeature icf = repo.getFeature(IndexCreationFeature.class).get(); + try { + icf.setLocalIndexPath(getIndexPath(repo)); + } catch (IOException e) { + log.error("Could not set local index path for {}. New URI: {}", repo.getId(), icf.getIndexPath()); + } + } + } + + @Override + public ArchivaIndexingContext mergeContexts(Repository destinationRepo, List contexts, boolean packIndex) throws UnsupportedOperationException, IndexCreationFailedException { + return null; + } + + + + private StorageAsset getIndexPath( Repository repo) throws IOException { + IndexCreationFeature icf = repo.getFeature(IndexCreationFeature.class).get(); + Path repoDir = repo.getRoot().getFilePath(); + URI indexDir = icf.getIndexPath(); + String indexPath = indexDir.getPath(); + Path indexDirectory = null; + FilesystemStorage fsStorage = (FilesystemStorage) repo.getRoot().getStorage(); + if ( ! StringUtils.isEmpty(indexDir.toString( ) ) ) + { + + indexDirectory = PathUtil.getPathFromUri( indexDir ); + // not absolute so create it in repository directory + if ( indexDirectory.isAbsolute( ) ) + { + indexPath = indexDirectory.getFileName().toString(); + fsStorage = new FilesystemStorage(indexDirectory.getParent(), new DefaultFileLockManager()); + } + else + { + indexDirectory = repoDir.resolve( indexDirectory ); + } + } + else + { + indexDirectory = repoDir.resolve( ".index" ); + indexPath = ".index"; + } + + if ( !Files.exists( indexDirectory ) ) + { + Files.createDirectories( indexDirectory ); + } + return new FilesystemAsset( fsStorage, indexPath, indexDirectory ); + } + + private IndexingContext createRemoteContext(RemoteRepository remoteRepository ) throws IOException + { + Path appServerBase = archivaConfiguration.getAppServerBaseDir( ); + + String contextKey = "remote-" + remoteRepository.getId( ); + + + // create remote repository path + Path repoDir = remoteRepository.getRoot().getFilePath(); + if ( !Files.exists( repoDir ) ) + { + Files.createDirectories( repoDir ); + } + + StorageAsset indexDirectory = null; + + // is there configured indexDirectory ? + if ( remoteRepository.supportsFeature( RemoteIndexFeature.class ) ) + { + RemoteIndexFeature rif = remoteRepository.getFeature( RemoteIndexFeature.class ).get( ); + indexDirectory = getIndexPath(remoteRepository); + String remoteIndexUrl = calculateIndexRemoteUrl( remoteRepository.getLocation( ), rif ); + try + { + + return getIndexingContext( remoteRepository, contextKey, repoDir, indexDirectory, remoteIndexUrl ); + } + catch ( IndexFormatTooOldException e ) + { + // existing index with an old lucene format so we need to delete it!!! + // delete it first then recreate it. + log.warn( "the index of repository {} is too old we have to delete and recreate it", // + remoteRepository.getId( ) ); + org.apache.archiva.common.utils.FileUtils.deleteDirectory( indexDirectory.getFilePath() ); + return getIndexingContext( remoteRepository, contextKey, repoDir, indexDirectory, remoteIndexUrl ); + + } + } + else + { + throw new IOException( "No remote index defined" ); + } + } + + private IndexingContext getIndexingContext( Repository repository, String contextKey, Path repoDir, StorageAsset indexDirectory, String indexUrl ) throws IOException + { + return indexer.createIndexingContext( contextKey, repository.getId( ), repoDir.toFile( ), indexDirectory.getFilePath().toFile( ), + repository.getLocation( ) == null ? null : repository.getLocation( ).toString( ), + indexUrl, + true, false, + indexCreators ); + } + + private IndexingContext createManagedContext( ManagedRepository repository ) throws IOException + { + + IndexingContext context; + // take care first about repository location as can be relative + Path repositoryDirectory = repository.getRoot().getFilePath(); + + if ( !Files.exists( repositoryDirectory ) ) + { + try + { + Files.createDirectories( repositoryDirectory ); + } + catch ( IOException e ) + { + log.error( "Could not create directory {}", repositoryDirectory ); + } + } + + StorageAsset indexDirectory = null; + + if ( repository.supportsFeature( IndexCreationFeature.class ) ) + { + indexDirectory = getIndexPath(repository); + + String indexUrl = repositoryDirectory.toUri( ).toURL( ).toExternalForm( ); + try + { + context = getIndexingContext( repository, repository.getId( ), repositoryDirectory, indexDirectory, indexUrl ); + context.setSearchable( repository.isScanned( ) ); + } + catch ( IndexFormatTooOldException e ) + { + // existing index with an old lucene format so we need to delete it!!! + // delete it first then recreate it. + log.warn( "the index of repository {} is too old we have to delete and recreate it", // + repository.getId( ) ); + org.apache.archiva.common.utils.FileUtils.deleteDirectory( indexDirectory.getFilePath() ); + context = getIndexingContext( repository, repository.getId( ), repositoryDirectory, indexDirectory, indexUrl ); + context.setSearchable( repository.isScanned( ) ); + } + return context; + } + else + { + throw new IOException( "No repository index defined" ); + } + } + + private String calculateIndexRemoteUrl( URI baseUri, RemoteIndexFeature rif ) + { + if ( rif.getIndexUri( ) == null ) + { + return baseUri.resolve( ".index" ).toString( ); + } + else + { + return baseUri.resolve( rif.getIndexUri( ) ).toString( ); + } + } + + private static final class DownloadListener + implements TransferListener + { + private Logger log = LoggerFactory.getLogger( getClass( ) ); + + private String resourceName; + + private long startTime; + + private int totalLength = 0; + + @Override + public void transferInitiated( TransferEvent transferEvent ) + { + startTime = System.currentTimeMillis( ); + resourceName = transferEvent.getResource( ).getName( ); + log.debug( "initiate transfer of {}", resourceName ); + } + + @Override + public void transferStarted( TransferEvent transferEvent ) + { + this.totalLength = 0; + resourceName = transferEvent.getResource( ).getName( ); + log.info( "start transfer of {}", transferEvent.getResource( ).getName( ) ); + } + + @Override + public void transferProgress( TransferEvent transferEvent, byte[] buffer, int length ) + { + log.debug( "transfer of {} : {}/{}", transferEvent.getResource( ).getName( ), buffer.length, length ); + this.totalLength += length; + } + + @Override + public void transferCompleted( TransferEvent transferEvent ) + { + resourceName = transferEvent.getResource( ).getName( ); + long endTime = System.currentTimeMillis( ); + log.info( "end of transfer file {} {} kb: {}s", transferEvent.getResource( ).getName( ), + this.totalLength / 1024, ( endTime - startTime ) / 1000 ); + } + + @Override + public void transferError( TransferEvent transferEvent ) + { + log.info( "error of transfer file {}: {}", transferEvent.getResource( ).getName( ), + transferEvent.getException( ).getMessage( ), transferEvent.getException( ) ); + } + + @Override + public void debug( String message ) + { + log.debug( "transfer debug {}", message ); + } + } + + private static class WagonResourceFetcher + implements ResourceFetcher + { + + Logger log; + + Path tempIndexDirectory; + + Wagon wagon; + + RemoteRepository remoteRepository; + + private WagonResourceFetcher( Logger log, Path tempIndexDirectory, Wagon wagon, + RemoteRepository remoteRepository ) + { + this.log = log; + this.tempIndexDirectory = tempIndexDirectory; + this.wagon = wagon; + this.remoteRepository = remoteRepository; + } + + @Override + public void connect( String id, String url ) + throws IOException + { + //no op + } + + @Override + public void disconnect( ) + throws IOException + { + // no op + } + + @Override + public InputStream retrieve(String name ) + throws IOException, FileNotFoundException + { + try + { + log.info( "index update retrieve file, name:{}", name ); + Path file = tempIndexDirectory.resolve( name ); + Files.deleteIfExists( file ); + file.toFile( ).deleteOnExit( ); + wagon.get( addParameters( name, remoteRepository ), file.toFile( ) ); + return Files.newInputStream( file ); + } + catch ( AuthorizationException | TransferFailedException e ) + { + throw new IOException( e.getMessage( ), e ); + } + catch ( ResourceDoesNotExistException e ) + { + FileNotFoundException fnfe = new FileNotFoundException( e.getMessage( ) ); + fnfe.initCause( e ); + throw fnfe; + } + } + + // FIXME remove crappy copy/paste + protected String addParameters( String path, RemoteRepository remoteRepository ) + { + if ( remoteRepository.getExtraParameters( ).isEmpty( ) ) + { + return path; + } + + boolean question = false; + + StringBuilder res = new StringBuilder( path == null ? "" : path ); + + for ( Map.Entry entry : remoteRepository.getExtraParameters( ).entrySet( ) ) + { + if ( !question ) + { + res.append( '?' ).append( entry.getKey( ) ).append( '=' ).append( entry.getValue( ) ); + } + } + + return res.toString( ); + } + + } +} diff --git a/archiva-modules/archiva-maven/archiva-maven-repository/src/test/java/org/apache/archiva/maven/repository/mock/MavenIndexContextMock.java b/archiva-modules/archiva-maven/archiva-maven-repository/src/test/java/org/apache/archiva/maven/repository/mock/MavenIndexContextMock.java new file mode 100644 index 000000000..875c3ee96 --- /dev/null +++ b/archiva-modules/archiva-maven/archiva-maven-repository/src/test/java/org/apache/archiva/maven/repository/mock/MavenIndexContextMock.java @@ -0,0 +1,148 @@ +package org.apache.archiva.maven.repository.mock; + +/* + * 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.filelock.DefaultFileLockManager; +import org.apache.archiva.indexer.ArchivaIndexingContext; +import org.apache.archiva.repository.Repository; +import org.apache.archiva.repository.storage.StorageAsset; +import org.apache.archiva.repository.storage.fs.FilesystemStorage; +import org.apache.maven.index.context.IndexingContext; + +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.NoSuchFileException; +import java.sql.Date; +import java.time.ZonedDateTime; +import java.util.Set; + +/** + * Maven implementation of index context + */ +public class MavenIndexContextMock implements ArchivaIndexingContext { + + private boolean open = true; + private IndexingContext delegate; + private Repository repository; + private FilesystemStorage indexStorage; + + MavenIndexContextMock(Repository repository, IndexingContext delegate) throws IOException { + this.delegate = delegate; + this.repository = repository; + indexStorage = new FilesystemStorage(delegate.getIndexDirectoryFile().toPath(), new DefaultFileLockManager()); + + } + + @Override + public String getId() { + return delegate.getId(); + } + + @Override + public Repository getRepository() { + return repository; + } + + @Override + public StorageAsset getPath() { + return indexStorage.getRoot(); + } + + @Override + public boolean isEmpty() throws IOException { + return Files.list(delegate.getIndexDirectoryFile().toPath()).count()==0; + } + + @Override + public void commit() throws IOException { + delegate.commit(); + } + + @Override + public void rollback() throws IOException { + delegate.rollback(); + } + + @Override + public void optimize() throws IOException { + delegate.optimize(); + } + + @Override + public void close(boolean deleteFiles) throws IOException { + open = false; + try { + delegate.close(deleteFiles); + } catch (NoSuchFileException e) { + // Ignore missing directory + } + } + + @Override + public void close() throws IOException { + open = false; + try { + delegate.close(false); + } catch (NoSuchFileException e) { + // Ignore missing directory + } + } + + @Override + public boolean isOpen() { + return open; + } + + @Override + public void purge() throws IOException { + delegate.purge(); + } + + @Override + public boolean supports(Class clazz) { + return IndexingContext.class.equals(clazz); + } + + @SuppressWarnings( "unchecked" ) + @Override + public T getBaseContext(Class clazz) throws UnsupportedOperationException { + if (IndexingContext.class.equals(clazz)) { + return (T) delegate; + } else { + throw new UnsupportedOperationException("The class "+clazz+" is not supported by the maven indexer"); + } + } + + @Override + public Set getGroups() throws IOException { + return delegate.getAllGroups(); + } + + @Override + public void updateTimestamp(boolean save) throws IOException { + delegate.updateTimestamp(save); + } + + @Override + public void updateTimestamp(boolean save, ZonedDateTime time) throws IOException { + delegate.updateTimestamp(save, Date.from(time.toInstant())); + } + + +} diff --git a/archiva-modules/archiva-maven/archiva-maven-repository/src/test/java/org/apache/archiva/maven/repository/mock/MockRepositoryArchivaTaskScheduler.java b/archiva-modules/archiva-maven/archiva-maven-repository/src/test/java/org/apache/archiva/maven/repository/mock/MockRepositoryArchivaTaskScheduler.java new file mode 100644 index 000000000..a2ae181da --- /dev/null +++ b/archiva-modules/archiva-maven/archiva-maven-repository/src/test/java/org/apache/archiva/maven/repository/mock/MockRepositoryArchivaTaskScheduler.java @@ -0,0 +1,57 @@ +package org.apache.archiva.maven.repository.mock; +/* + * 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.components.taskqueue.TaskQueueException; +import org.apache.archiva.scheduler.repository.model.RepositoryArchivaTaskScheduler; +import org.apache.archiva.scheduler.repository.model.RepositoryTask; +import org.springframework.stereotype.Service; + +/** + * @author Olivier Lamy + */ +@Service ("archivaTaskScheduler#repositoryMock") +public class MockRepositoryArchivaTaskScheduler + implements RepositoryArchivaTaskScheduler +{ + @Override + public boolean isProcessingRepositoryTask( String repositoryId ) + { + return false; + } + + @Override + public boolean isProcessingRepositoryTask( RepositoryTask task ) + { + return false; + } + + @Override + public void queueTask( RepositoryTask task ) + throws TaskQueueException + { + // no op + } + + @Override + public boolean unQueueTask( RepositoryTask task ) + throws TaskQueueException + { + return false; + } +} diff --git a/archiva-modules/archiva-maven/archiva-maven-repository/src/test/java/org/apache/archiva/maven/repository/mock/RepositoryRegistryMock.java b/archiva-modules/archiva-maven/archiva-maven-repository/src/test/java/org/apache/archiva/maven/repository/mock/RepositoryRegistryMock.java new file mode 100644 index 000000000..f5a1422d1 --- /dev/null +++ b/archiva-modules/archiva-maven/archiva-maven-repository/src/test/java/org/apache/archiva/maven/repository/mock/RepositoryRegistryMock.java @@ -0,0 +1,62 @@ +package org.apache.archiva.maven.repository.mock; + +/* + * 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.repository.ManagedRepository; +import org.apache.archiva.repository.Repository; +import org.apache.archiva.repository.RepositoryException; +import org.apache.archiva.repository.base.ArchivaRepositoryRegistry; +import org.apache.archiva.repository.base.ConfigurationHandler; +import org.apache.archiva.repository.validation.RepositoryValidator; + +import java.util.List; +import java.util.Map; +import java.util.TreeMap; + +public class RepositoryRegistryMock extends ArchivaRepositoryRegistry +{ + + private Map managedRepositories = new TreeMap<>(); + + public RepositoryRegistryMock( ConfigurationHandler configurationHandler, List> validatorList ) + { + super( configurationHandler, validatorList ); + } + + @Override + public ManagedRepository putRepository(ManagedRepository managedRepository) throws RepositoryException + { + managedRepositories.put(managedRepository.getId(), managedRepository); + return managedRepository; + } + + @Override + public ManagedRepository getManagedRepository(String repoId) { + return managedRepositories.get(repoId); + } + + @Override + public Repository getRepository( String repoId) { + if (managedRepositories.containsKey(repoId)) { + return managedRepositories.get(repoId); + } else { + return null; + } + } +} diff --git a/archiva-modules/archiva-maven/archiva-maven-repository/src/test/java/org/apache/archiva/maven/repository/mock/TestMetadataResolver.java b/archiva-modules/archiva-maven/archiva-maven-repository/src/test/java/org/apache/archiva/maven/repository/mock/TestMetadataResolver.java new file mode 100644 index 000000000..9dbe353a5 --- /dev/null +++ b/archiva-modules/archiva-maven/archiva-maven-repository/src/test/java/org/apache/archiva/maven/repository/mock/TestMetadataResolver.java @@ -0,0 +1,89 @@ +package org.apache.archiva.maven.repository.mock; + +/* + * 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.metadata.model.ArtifactMetadata; +import org.apache.archiva.metadata.model.ProjectVersionMetadata; +import org.apache.archiva.metadata.model.ProjectVersionReference; +import org.apache.archiva.metadata.repository.MetadataResolutionException; +import org.apache.archiva.metadata.repository.MetadataResolver; +import org.apache.archiva.metadata.repository.RepositorySession; +import org.springframework.stereotype.Service; + +import java.util.Collection; + +// FIXME: remove - this is useless, better to mock it or avoid needing it +@Service( "metadataResolver#test" ) +public class TestMetadataResolver + implements MetadataResolver +{ + @Override + public ProjectVersionMetadata resolveProjectVersion( RepositorySession session, String repoId, String namespace, + String projectId, String projectVersion ) + throws MetadataResolutionException + { + return null; + } + + @Override + public Collection resolveProjectReferences( RepositorySession session, String repoId, + String namespace, String projectId, + String projectVersion ) + throws MetadataResolutionException + { + return null; + } + + @Override + public Collection resolveRootNamespaces( RepositorySession session, String repoId ) + throws MetadataResolutionException + { + return null; + } + + @Override + public Collection resolveNamespaces( RepositorySession session, String repoId, String namespace ) + throws MetadataResolutionException + { + return null; + } + + @Override + public Collection resolveProjects( RepositorySession session, String repoId, String namespace ) + throws MetadataResolutionException + { + return null; + } + + @Override + public Collection resolveProjectVersions( RepositorySession session, String repoId, String namespace, + String projectId ) + throws MetadataResolutionException + { + return null; + } + + @Override + public Collection resolveArtifacts( RepositorySession session, String repoId, String namespace, + String projectId, String projectVersion ) + throws MetadataResolutionException + { + return null; + } +} diff --git a/archiva-modules/archiva-maven/archiva-maven-repository/src/test/java/org/apache/archiva/maven/repository/mock/configuration/MockRepoAdmin.java b/archiva-modules/archiva-maven/archiva-maven-repository/src/test/java/org/apache/archiva/maven/repository/mock/configuration/MockRepoAdmin.java new file mode 100644 index 000000000..f069d8374 --- /dev/null +++ b/archiva-modules/archiva-maven/archiva-maven-repository/src/test/java/org/apache/archiva/maven/repository/mock/configuration/MockRepoAdmin.java @@ -0,0 +1,323 @@ +package org.apache.archiva.maven.repository.mock.configuration; +/* + * 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.admin.model.AuditInformation; +import org.apache.archiva.admin.model.RepositoryAdminException; +import org.apache.archiva.admin.model.beans.ManagedRepository; +import org.apache.archiva.admin.model.beans.NetworkProxy; +import org.apache.archiva.admin.model.beans.ProxyConnector; +import org.apache.archiva.admin.model.beans.ProxyConnectorRule; +import org.apache.archiva.admin.model.beans.RemoteRepository; +import org.apache.archiva.admin.model.managed.ManagedRepositoryAdmin; +import org.apache.archiva.admin.model.networkproxy.NetworkProxyAdmin; +import org.apache.archiva.admin.model.proxyconnector.ProxyConnectorAdmin; +import org.apache.archiva.admin.model.proxyconnector.ProxyConnectorOrderComparator; +import org.apache.archiva.admin.model.remote.RemoteRepositoryAdmin; +import org.apache.archiva.configuration.ArchivaConfiguration; +import org.apache.archiva.configuration.ManagedRepositoryConfiguration; +import org.apache.archiva.configuration.ProxyConnectorConfiguration; +import org.apache.archiva.configuration.RemoteRepositoryConfiguration; +import org.apache.commons.lang3.StringUtils; +import org.modelmapper.ModelMapper; +import org.springframework.stereotype.Service; + +import javax.inject.Inject; +import javax.inject.Named; +import java.util.ArrayList; +import java.util.Collections; +import java.util.HashMap; +import java.util.Iterator; +import java.util.List; +import java.util.Locale; +import java.util.Map; + +/** + * @author Olivier Lamy + */ +@Service +public class MockRepoAdmin + implements RemoteRepositoryAdmin, ManagedRepositoryAdmin, ProxyConnectorAdmin, NetworkProxyAdmin +{ + @Inject + @Named ( "archivaConfiguration#test" ) + private ArchivaConfiguration archivaConfiguration; + + @Override + public List getRemoteRepositories() + throws RepositoryAdminException + { + List remoteRepositories = + new ArrayList<>( archivaConfiguration.getConfiguration().getRemoteRepositories().size() ); + for ( RemoteRepositoryConfiguration repositoryConfiguration : archivaConfiguration.getConfiguration().getRemoteRepositories() ) + { + RemoteRepository remoteRepository = + new RemoteRepository( Locale.getDefault(), repositoryConfiguration.getId(), repositoryConfiguration.getName(), + repositoryConfiguration.getUrl(), repositoryConfiguration.getLayout(), + repositoryConfiguration.getUsername(), repositoryConfiguration.getPassword(), + repositoryConfiguration.getTimeout() ); + remoteRepository.setDownloadRemoteIndex( repositoryConfiguration.isDownloadRemoteIndex() ); + remoteRepository.setRemoteIndexUrl( repositoryConfiguration.getRemoteIndexUrl() ); + remoteRepository.setCronExpression( repositoryConfiguration.getRefreshCronExpression() ); + remoteRepository.setIndexDirectory( repositoryConfiguration.getIndexDir() ); + remoteRepository.setRemoteDownloadNetworkProxyId( + repositoryConfiguration.getRemoteDownloadNetworkProxyId() ); + remoteRepository.setRemoteDownloadTimeout( repositoryConfiguration.getRemoteDownloadTimeout() ); + remoteRepository.setDownloadRemoteIndexOnStartup( + repositoryConfiguration.isDownloadRemoteIndexOnStartup() ); + remoteRepositories.add( remoteRepository ); + } + return remoteRepositories; + } + + @Override + public RemoteRepository getRemoteRepository( String repositoryId ) + throws RepositoryAdminException + { + for ( RemoteRepository remoteRepository : getRemoteRepositories() ) + { + if ( StringUtils.equals( repositoryId, remoteRepository.getId() ) ) + { + return remoteRepository; + } + } + return null; + } + + @Override + public Boolean deleteRemoteRepository( String repositoryId, AuditInformation auditInformation ) + throws RepositoryAdminException + { + return null; //To change body of implemented methods use File | Settings | File Templates. + } + + @Override + public Boolean addRemoteRepository( RemoteRepository remoteRepository, AuditInformation auditInformation ) + throws RepositoryAdminException + { + return null; //To change body of implemented methods use File | Settings | File Templates. + } + + @Override + public Boolean updateRemoteRepository( RemoteRepository remoteRepository, AuditInformation auditInformation ) + throws RepositoryAdminException + { + return null; //To change body of implemented methods use File | Settings | File Templates. + } + + @Override + public Map getRemoteRepositoriesAsMap() + throws RepositoryAdminException + { + return null; //To change body of implemented methods use File | Settings | File Templates. + } + + @Override + public List getManagedRepositories() + throws RepositoryAdminException + { + return null; //To change body of implemented methods use File | Settings | File Templates. + } + + @Override + public Map getManagedRepositoriesAsMap() + throws RepositoryAdminException + { + return null; //To change body of implemented methods use File | Settings | File Templates. + } + + @Override + public ManagedRepository getManagedRepository( String repositoryId ) + throws RepositoryAdminException + { + for ( ManagedRepositoryConfiguration repoConfig : archivaConfiguration.getConfiguration().getManagedRepositories() ) + { + if ( StringUtils.equals( repositoryId, repoConfig.getId() ) ) + { + return new ManagedRepository( Locale.getDefault(), repoConfig.getId(), repoConfig.getName(), repoConfig.getLocation(), + repoConfig.getLayout(), repoConfig.isSnapshots(), repoConfig.isReleases(), + repoConfig.isBlockRedeployments(), repoConfig.getRefreshCronExpression(), + repoConfig.getIndexDir(), repoConfig.isScanned(), + repoConfig.getRetentionPeriod(), repoConfig.getRetentionCount(), + repoConfig.isDeleteReleasedSnapshots(), false ); + } + } + return null; + } + + @Override + public Boolean deleteManagedRepository( String repositoryId, AuditInformation auditInformation, + boolean deleteContent ) + throws RepositoryAdminException + { + return null; //To change body of implemented methods use File | Settings | File Templates. + } + + @Override + public Boolean addManagedRepository( ManagedRepository managedRepository, boolean needStageRepo, + AuditInformation auditInformation ) + throws RepositoryAdminException + { + return null; //To change body of implemented methods use File | Settings | File Templates. + } + + @Override + public Boolean updateManagedRepository( ManagedRepository managedRepository, boolean needStageRepo, + AuditInformation auditInformation, boolean resetStats ) + throws RepositoryAdminException + { + return null; //To change body of implemented methods use File | Settings | File Templates. + } + + + @Override + public List getProxyConnectors() + throws RepositoryAdminException + { + List proxyConnectorConfigurations = + archivaConfiguration.getConfiguration().getProxyConnectors(); + List proxyConnectors = new ArrayList<>( proxyConnectorConfigurations.size() ); + for ( ProxyConnectorConfiguration configuration : proxyConnectorConfigurations ) + { + proxyConnectors.add( getProxyConnector( configuration ) ); + } + Collections.sort( proxyConnectors, ProxyConnectorOrderComparator.getInstance() ); + return proxyConnectors; + } + + @Override + public ProxyConnector getProxyConnector( String sourceRepoId, String targetRepoId ) + throws RepositoryAdminException + { + return null; //To change body of implemented methods use File | Settings | File Templates. + } + + @Override + public Boolean addProxyConnector( ProxyConnector proxyConnector, AuditInformation auditInformation ) + throws RepositoryAdminException + { + return null; //To change body of implemented methods use File | Settings | File Templates. + } + + @Override + public Boolean deleteProxyConnector( ProxyConnector proxyConnector, AuditInformation auditInformation ) + throws RepositoryAdminException + { + return null; //To change body of implemented methods use File | Settings | File Templates. + } + + @Override + public Boolean updateProxyConnector( ProxyConnector proxyConnector, AuditInformation auditInformation ) + throws RepositoryAdminException + { + return null; + } + + @Override + public Map> getProxyConnectorAsMap() + throws RepositoryAdminException + { + Map> proxyConnectorMap = new HashMap<>(); + + Iterator it = getProxyConnectors().iterator(); + while ( it.hasNext() ) + { + ProxyConnector proxyConfig = it.next(); + String key = proxyConfig.getSourceRepoId(); + + List connectors = proxyConnectorMap.get( key ); + if ( connectors == null ) + { + connectors = new ArrayList<>( 1 ); + proxyConnectorMap.put( key, connectors ); + } + + connectors.add( proxyConfig ); + + Collections.sort( connectors, ProxyConnectorOrderComparator.getInstance() ); + } + + return proxyConnectorMap; + } + + @Override + public List getNetworkProxies() + throws RepositoryAdminException + { + return null; //To change body of implemented methods use File | Settings | File Templates. + } + + @Override + public NetworkProxy getNetworkProxy( String networkProxyId ) + throws RepositoryAdminException + { + return null; //To change body of implemented methods use File | Settings | File Templates. + } + + @Override + public void addNetworkProxy( NetworkProxy networkProxy, AuditInformation auditInformation ) + throws RepositoryAdminException + { + //To change body of implemented methods use File | Settings | File Templates. + } + + @Override + public void updateNetworkProxy( NetworkProxy networkProxy, AuditInformation auditInformation ) + throws RepositoryAdminException + { + //To change body of implemented methods use File | Settings | File Templates. + } + + @Override + public void deleteNetworkProxy( String networkProxyId, AuditInformation auditInformation ) + throws RepositoryAdminException + { + //To change body of implemented methods use File | Settings | File Templates. + } + + protected ProxyConnector getProxyConnector( ProxyConnectorConfiguration proxyConnectorConfiguration ) + { + return proxyConnectorConfiguration == null + ? null + : new ModelMapper().map( proxyConnectorConfiguration, ProxyConnector.class ); + } + + public List getProxyConnectorRules() + throws RepositoryAdminException + { + return null; + } + + public void addProxyConnectorRule( ProxyConnectorRule proxyConnectorRule ) + throws RepositoryAdminException + { + + } + + public void deleteProxyConnectorRule( ProxyConnectorRule proxyConnectorRule ) + throws RepositoryAdminException + { + + } + + public void updateProxyConnectorRule( ProxyConnectorRule proxyConnectorRule ) + throws RepositoryAdminException + { + + } +} diff --git a/archiva-modules/archiva-maven/archiva-maven-repository/src/test/java/org/apache/archiva/maven/repository/mock/configuration/StubConfiguration.java b/archiva-modules/archiva-maven/archiva-maven-repository/src/test/java/org/apache/archiva/maven/repository/mock/configuration/StubConfiguration.java new file mode 100644 index 000000000..474fd4a7b --- /dev/null +++ b/archiva-modules/archiva-maven/archiva-maven-repository/src/test/java/org/apache/archiva/maven/repository/mock/configuration/StubConfiguration.java @@ -0,0 +1,159 @@ +package org.apache.archiva.maven.repository.mock.configuration; + +/* + * 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.components.registry.Registry; +import org.apache.archiva.components.registry.RegistryException; +import org.apache.archiva.components.registry.RegistryListener; +import org.apache.archiva.configuration.ArchivaConfiguration; +import org.apache.archiva.configuration.Configuration; +import org.apache.archiva.configuration.ConfigurationListener; +import org.apache.archiva.configuration.IndeterminateConfigurationException; +import org.apache.archiva.configuration.RepositoryScanningConfiguration; +import org.apache.commons.lang3.StringUtils; +import org.springframework.stereotype.Service; + +import java.nio.file.Path; +import java.nio.file.Paths; +import java.util.List; +import java.util.Locale; + +@Service("archivaConfiguration#mocked") +public class StubConfiguration + implements ArchivaConfiguration +{ + private Configuration configuration = new Configuration(); + + StubConfiguration() { + configuration.setRepositoryScanning( new RepositoryScanningConfiguration() ); + } + + @Override + public Configuration getConfiguration() + { + return configuration; + } + + @Override + public void save( Configuration configuration ) + throws RegistryException, IndeterminateConfigurationException + { + this.configuration = configuration; + } + + @Override + public void save( Configuration configuration, String eventTag ) throws RegistryException, IndeterminateConfigurationException + { + this.configuration = configuration; + } + + @Override + public boolean isDefaulted() + { + return false; + } + + @Override + public void addListener( ConfigurationListener listener ) + { + // throw new UnsupportedOperationException(); + } + + @Override + public void removeListener( ConfigurationListener listener ) + { + throw new UnsupportedOperationException(); + } + + @Override + public void addChangeListener( RegistryListener listener ) + { + // throw new UnsupportedOperationException(); + } + + @Override + public void removeChangeListener( RegistryListener listener ) + { + throw new UnsupportedOperationException(); + } + + @Override + public void reload() + { + // no op + } + + @Override + public Locale getDefaultLocale( ) + { + return Locale.getDefault(); + } + + @Override + public List getLanguagePriorities( ) + { + return Locale.LanguageRange.parse( "en,fr,de" ); + } + + @Override + public Path getAppServerBaseDir() { + if (System.getProperties().containsKey("appserver.base")) { + return Paths.get(System.getProperty("appserver.base")); + } else { + return Paths.get(""); + } + } + + @Override + public Path getRepositoryBaseDir() { + return getDataDirectory().resolve("repositories"); + } + + @Override + public Path getRemoteRepositoryBaseDir() { + return getDataDirectory().resolve("remotes"); + } + + @Override + public Path getRepositoryGroupBaseDir( ) + { + return getDataDirectory().resolve("group"); + } + + @Override + public Path getDataDirectory() { + if (configuration!=null && configuration.getArchivaRuntimeConfiguration()!=null && StringUtils.isNotEmpty(configuration.getArchivaRuntimeConfiguration().getDataDirectory())) { + Path dataDir = Paths.get(configuration.getArchivaRuntimeConfiguration().getDataDirectory()); + if (dataDir.isAbsolute()) { + return dataDir; + } else { + return getAppServerBaseDir().resolve(dataDir); + } + } else { + return getAppServerBaseDir().resolve("data"); + } + + } + + @Override + public Registry getRegistry( ) + { + return null; + } +} diff --git a/archiva-modules/archiva-maven/archiva-maven-repository/src/test/java/org/apache/archiva/maven/repository/mock/configuration/TestConfiguration.java b/archiva-modules/archiva-maven/archiva-maven-repository/src/test/java/org/apache/archiva/maven/repository/mock/configuration/TestConfiguration.java new file mode 100644 index 000000000..d398be9d0 --- /dev/null +++ b/archiva-modules/archiva-maven/archiva-maven-repository/src/test/java/org/apache/archiva/maven/repository/mock/configuration/TestConfiguration.java @@ -0,0 +1,148 @@ +package org.apache.archiva.maven.repository.mock.configuration; + +import org.apache.archiva.components.registry.Registry; +import org.apache.archiva.components.registry.RegistryException; +import org.apache.archiva.components.registry.RegistryListener; +import org.apache.archiva.configuration.ArchivaConfiguration; +import org.apache.archiva.configuration.Configuration; +import org.apache.archiva.configuration.ConfigurationListener; +import org.apache.archiva.configuration.IndeterminateConfigurationException; +import org.apache.commons.lang3.StringUtils; +import org.springframework.stereotype.Service; + +import java.nio.file.Path; +import java.nio.file.Paths; +import java.util.List; +import java.util.Locale; + +/* + * 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. + */ + +@Service("archivaConfiguration#test") +public class TestConfiguration + implements ArchivaConfiguration +{ + private Configuration configuration; + + @Override + public Configuration getConfiguration() + { + return configuration; + } + + @Override + public void save( Configuration configuration ) + throws RegistryException, IndeterminateConfigurationException + { + this.configuration = configuration; + } + + @Override + public void save( Configuration configuration, String eventTag ) throws RegistryException, IndeterminateConfigurationException + { + this.configuration = configuration; + } + + @Override + public boolean isDefaulted() + { + return false; + } + + @Override + public void addListener( ConfigurationListener listener ) + { + // no op + } + + @Override + public void removeListener( ConfigurationListener listener ) + { + // no op + } + + @Override + public void addChangeListener( RegistryListener listener ) + { + // no op + } + + @Override + public void removeChangeListener( RegistryListener listener ) + { + // no op + } + + @Override + public void reload() + { + // no op + } + + @Override + public Locale getDefaultLocale( ) + { + return Locale.getDefault(); + } + + @Override + public List getLanguagePriorities( ) + { + return Locale.LanguageRange.parse("en,fr,de"); + } + + @Override + public Path getAppServerBaseDir() { + if (System.getProperties().containsKey("appserver.base")) { + return Paths.get(System.getProperty("appserver.base")); + } else { + return Paths.get(""); + } + } + + @Override + public Path getRepositoryBaseDir() { + return getDataDirectory().resolve(""); + } + + @Override + public Path getRemoteRepositoryBaseDir() { + return getDataDirectory().resolve("remotes"); + } + + @Override + public Path getRepositoryGroupBaseDir() { + return getDataDirectory().resolve("groups"); + } + + @Override + public Path getDataDirectory() { + if (configuration!=null && configuration.getArchivaRuntimeConfiguration()!=null && + StringUtils.isNotEmpty(configuration.getArchivaRuntimeConfiguration().getDataDirectory())) { + return Paths.get(configuration.getArchivaRuntimeConfiguration().getDataDirectory()); + } else { + return getAppServerBaseDir().resolve("data"); + } + } + + @Override + public Registry getRegistry( ) + { + return null; + } +} diff --git a/archiva-modules/archiva-maven/archiva-maven-repository/src/test/java/org/apache/archiva/repository/maven/AbstractRepositoryLayerTestCase.java b/archiva-modules/archiva-maven/archiva-maven-repository/src/test/java/org/apache/archiva/repository/maven/AbstractRepositoryLayerTestCase.java deleted file mode 100644 index dc0dfc44a..000000000 --- a/archiva-modules/archiva-maven/archiva-maven-repository/src/test/java/org/apache/archiva/repository/maven/AbstractRepositoryLayerTestCase.java +++ /dev/null @@ -1,93 +0,0 @@ -package org.apache.archiva.repository.maven; - -/* - * 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.repository.ManagedRepositoryContent; -import org.apache.archiva.repository.RemoteRepositoryContent; -import org.apache.archiva.repository.RepositoryContentProvider; -import org.apache.archiva.test.utils.ArchivaSpringJUnit4ClassRunner; -import org.junit.Rule; -import org.junit.rules.TestName; -import org.junit.runner.RunWith; -import org.springframework.context.ApplicationContext; -import org.springframework.test.context.ContextConfiguration; - -import javax.inject.Inject; -import java.io.IOException; -import java.net.URI; -import java.net.URISyntaxException; -import java.nio.file.Path; -import java.nio.file.Paths; - -/** - * AbstractRepositoryLayerTestCase - * - * - */ -@RunWith( ArchivaSpringJUnit4ClassRunner.class ) -@ContextConfiguration( { "classpath*:/META-INF/spring-context.xml", "classpath:/spring-context-repository-conf.xml" } ) -public abstract class AbstractRepositoryLayerTestCase -{ - @Rule - public TestName name = new TestName(); - - @Inject - protected ApplicationContext applicationContext; - - protected MavenManagedRepository createRepository( String id, String name, Path location ) throws IOException { - MavenManagedRepository repo = MavenManagedRepository.newLocalInstance( id, name, location.getParent().toAbsolutePath()); - repo.setLocation( location.toAbsolutePath().toUri() ); - return repo; - } - - protected MavenRemoteRepository createRemoteRepository( String id, String name, String url ) throws URISyntaxException, IOException { - MavenRemoteRepository repo = MavenRemoteRepository.newLocalInstance(id, name, Paths.get("target/remotes")); - repo.setLocation( new URI( url ) ); - return repo; - } - - protected ManagedRepositoryContent createManagedRepositoryContent( String id, String name, Path location, - String layout ) - throws Exception - { - MavenManagedRepository repo = MavenManagedRepository.newLocalInstance( id, name, location.getParent() ); - repo.setLocation( location.toAbsolutePath().toUri() ); - repo.setLayout( layout ); - - RepositoryContentProvider provider = applicationContext.getBean( "repositoryContentProvider#maven", RepositoryContentProvider.class ); - ManagedRepositoryContent repoContent = - provider.createManagedContent( repo ); - - return repoContent; - } - - protected RemoteRepositoryContent createRemoteRepositoryContent( String id, String name, String url, String layout ) - throws Exception - { - MavenRemoteRepository repo = MavenRemoteRepository.newLocalInstance(id, name, Paths.get("target/remotes")); - repo.setLocation( new URI( url ) ); - repo.setLayout( layout ); - - RepositoryContentProvider provider = applicationContext.getBean( "repositoryContentProvider#maven", RepositoryContentProvider.class ); - RemoteRepositoryContent repoContent = - provider.createRemoteContent( repo ); - - return repoContent; - } -} diff --git a/archiva-modules/archiva-maven/archiva-maven-repository/src/test/java/org/apache/archiva/repository/maven/MavenRepositoryProviderTest.java b/archiva-modules/archiva-maven/archiva-maven-repository/src/test/java/org/apache/archiva/repository/maven/MavenRepositoryProviderTest.java deleted file mode 100644 index e98efb0ae..000000000 --- a/archiva-modules/archiva-maven/archiva-maven-repository/src/test/java/org/apache/archiva/repository/maven/MavenRepositoryProviderTest.java +++ /dev/null @@ -1,374 +0,0 @@ -package org.apache.archiva.repository.maven; - -/* - * 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.utils.FileUtils; -import org.apache.archiva.configuration.ArchivaRuntimeConfiguration; -import org.apache.archiva.configuration.ManagedRepositoryConfiguration; -import org.apache.archiva.configuration.RemoteRepositoryConfiguration; -import org.apache.archiva.configuration.RepositoryGroupConfiguration; -import org.apache.archiva.repository.EditableRepositoryGroup; -import org.apache.archiva.repository.ManagedRepository; -import org.apache.archiva.repository.ReleaseScheme; -import org.apache.archiva.repository.RemoteRepository; -import org.apache.archiva.repository.RepositoryException; -import org.apache.archiva.repository.RepositoryGroup; -import org.apache.archiva.repository.RepositoryRegistry; -import org.apache.archiva.repository.RepositoryType; -import org.apache.archiva.repository.UnsupportedFeatureException; -import org.apache.archiva.repository.base.PasswordCredentials; -import org.apache.archiva.repository.features.ArtifactCleanupFeature; -import org.apache.archiva.repository.features.IndexCreationFeature; -import org.apache.archiva.repository.features.RemoteIndexFeature; -import org.apache.archiva.repository.features.StagingRepositoryFeature; -import org.apache.archiva.repository.maven.metadata.storage.mock.MockConfiguration; -import org.junit.After; -import org.junit.Before; -import org.junit.Test; - -import java.io.IOException; -import java.net.URI; -import java.net.URISyntaxException; -import java.nio.file.Files; -import java.nio.file.Path; -import java.nio.file.Paths; -import java.time.Duration; -import java.time.Period; -import java.time.temporal.ChronoUnit; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.Map; - -import static org.junit.Assert.*; - -/** - * @author Martin Stockhammer - */ -public class MavenRepositoryProviderTest -{ - - MavenRepositoryProvider provider; - RepositoryRegistry reg; - - Path repoLocation; - - - @Before - public void setUp() - throws Exception - { - provider = new MavenRepositoryProvider( ); - MockConfiguration mockConfiguration =new MockConfiguration(); - mockConfiguration.getConfiguration().setArchivaRuntimeConfiguration( new ArchivaRuntimeConfiguration() ); - mockConfiguration.getConfiguration().getArchivaRuntimeConfiguration().setRepositoryBaseDirectory( "repositories" ); - provider.setArchivaConfiguration( mockConfiguration ); - - } - - @After - public void cleanUp() { - if (repoLocation!=null && Files.exists( repoLocation )) { - FileUtils.deleteQuietly( repoLocation ); - } - } - - @Test - public void provides( ) throws Exception - { - assertEquals(1, provider.provides().size()); - assertEquals( RepositoryType.MAVEN, provider.provides().iterator().next()); - } - - @Test - public void createManagedInstance( ) throws Exception - { - ManagedRepositoryConfiguration repo = new ManagedRepositoryConfiguration( ); - repo.setId("testm001"); - repo.setName("Managed Test Repo 001"); - repo.setDescription( "This is a managed test" ); - repo.setRetentionPeriod( 37 ); - repoLocation = Files.createTempDirectory( "test-repo-001"); - repo.setLocation( repoLocation.toAbsolutePath().toString() ); - repo.setSnapshots( true ); - repo.setReleases( true ); - repo.setRefreshCronExpression( "4 0 0 ? * TUE" ); - repo.setScanned( true ); - repo.setBlockRedeployments( true ); - repo.setDeleteReleasedSnapshots( true ); - repo.setRetentionCount( 33 ); - repo.setSkipPackedIndexCreation( true ); - repo.setStageRepoNeeded( true ); - repo.setIndexDir( "testmanaged/.index" ); - repo.setLayout( "maven2" ); - repo.setType( RepositoryType.MAVEN.toString() ); - - - ManagedRepository mr = provider.createManagedInstance( repo ); - assertNotNull(mr.getLocation()); - String repoUri = repoLocation.toUri().toString(); - assertTrue(Files.exists(repoLocation)); - repoUri = repoUri.substring( 0, repoUri.length()-1 ); - assertEquals(repoUri, mr.getLocation().toString()); - assertEquals("This is a managed test", mr.getDescription()); - assertEquals("Managed Test Repo 001", mr.getName()); - assertEquals(2, mr.getActiveReleaseSchemes().size()); - assertTrue( mr.getActiveReleaseSchemes().contains( ReleaseScheme.RELEASE )); - assertTrue( mr.getActiveReleaseSchemes().contains( ReleaseScheme.SNAPSHOT)); - assertEquals("testm001", mr.getId()); - assertTrue(mr.blocksRedeployments()); - assertEquals("4 0 0 ? * TUE", mr.getSchedulingDefinition()); - assertTrue(mr.isScanned()); - ArtifactCleanupFeature artifactCleanupFeature = mr.getFeature( ArtifactCleanupFeature.class ).get(); - assertEquals( Period.ofDays( 37), artifactCleanupFeature.getRetentionPeriod()); - assertTrue(artifactCleanupFeature.isDeleteReleasedSnapshots()); - assertEquals(33, artifactCleanupFeature.getRetentionCount()); - - IndexCreationFeature indexCreationFeature = mr.getFeature( IndexCreationFeature.class ).get(); - assertNotNull(indexCreationFeature.getIndexPath()); - assertEquals("testmanaged/.index", indexCreationFeature.getIndexPath().toString()); - assertFalse(indexCreationFeature.getIndexPath().isAbsolute()); - assertTrue(indexCreationFeature.isSkipPackedIndexCreation()); - - StagingRepositoryFeature stagingRepositoryFeature = mr.getFeature( StagingRepositoryFeature.class ).get(); - assertTrue(stagingRepositoryFeature.isStageRepoNeeded()); - assertNull(stagingRepositoryFeature.getStagingRepository()); - - - } - - @Test - public void createRemoteInstance( ) throws Exception - { - RemoteRepositoryConfiguration repo = new RemoteRepositoryConfiguration( ); - repo.setUsername("testuser001"); - repo.setPassword( "pwd0000abc" ); - repo.setCheckPath( "test/check.html" ); - repo.setTimeout( 50 ); - repo.setUrl( "https://repo.maven.apache.org/maven2/test" ); - repo.setDownloadRemoteIndex( true ); - repo.setDownloadRemoteIndexOnStartup( true ); - Map header = new HashMap<>( ); - header.put("header1","value1"); - header.put("header2","value2"); - repo.setExtraHeaders( header ); - Map params = new HashMap<>( ); - params.put("param1","pval1"); - params.put("param2","pval2"); - repo.setExtraParameters( params ); - repo.setRefreshCronExpression( "0 1 07 ? * MON" ); - repo.setRemoteDownloadTimeout( 333 ); - repo.setRemoteIndexUrl( "testremote/.index" ); - repo.setDescription( "This is a test" ); - repo.setId( "test001" ); - repo.setName( "Remote Test Repo 001" ); - repo.setIndexDir( "testindex/.index" ); - repo.setLayout( "maven2" ); - repo.setType( RepositoryType.MAVEN.toString() ); - repo.setIndexDir( "local/.index" ); - - RemoteRepository mr = provider.createRemoteInstance( repo ); - assertEquals("test001", mr.getId()); - assertEquals("This is a test", mr.getDescription()); - assertNotNull(mr.getLocation()); - assertEquals("https://repo.maven.apache.org/maven2/test", mr.getLocation().toString()); - assertEquals("Remote Test Repo 001", mr.getName()); - assertEquals("test001", mr.getId()); - assertEquals("0 1 07 ? * MON", mr.getSchedulingDefinition()); - assertEquals(50, mr.getTimeout().get( ChronoUnit.SECONDS )); - assertTrue(mr.isScanned()); - assertNotNull(mr.getLoginCredentials()); - assertTrue(mr.getLoginCredentials() instanceof PasswordCredentials ); - PasswordCredentials creds = (PasswordCredentials) mr.getLoginCredentials(); - assertEquals("testuser001", creds.getUsername()); - assertEquals("pwd0000abc", new String(creds.getPassword())); - assertEquals("value1", mr.getExtraHeaders().get("header1")); - assertEquals("pval2", mr.getExtraParameters().get("param2")); - assertEquals( "maven2", mr.getLayout()); - try - { - ArtifactCleanupFeature artifactCleanupFeature = mr.getFeature( ArtifactCleanupFeature.class ).get( ); - throw new Exception("artifactCleanupFeature should not be available"); - } catch ( UnsupportedFeatureException e ) { - // correct - } - - IndexCreationFeature indexCreationFeature = mr.getFeature( IndexCreationFeature.class ).get( ); - assertEquals("local/.index", indexCreationFeature.getIndexPath().toString()); - try - { - StagingRepositoryFeature stagingRepositoryFeature = mr.getFeature( StagingRepositoryFeature.class ).get( ); - throw new Exception("stagingRepositoryFeature should not be available"); - } catch (UnsupportedFeatureException e) { - // correct - } - RemoteIndexFeature remoteIndexFeature = mr.getFeature( RemoteIndexFeature.class ).get(); - assertNull(remoteIndexFeature.getProxyId()); - } - - @Test - public void getManagedConfiguration() throws Exception { - MavenManagedRepository repo = MavenManagedRepository.newLocalInstance( "test01", "My Test repo", Paths.get("target/repositories") ); - - repo.setLocation( new URI("target/this.is/a/test") ); - repo.setScanned( true ); - repo.setDescription( repo.getPrimaryLocale(), "This is a description" ); - repo.setLayout( "maven2" ); - repo.setBlocksRedeployment( true ); - repo.setName( repo.getPrimaryLocale(), "test0002" ); - repo.setSchedulingDefinition( "0 0 05 ? * WED" ); - repo.addActiveReleaseScheme( ReleaseScheme.RELEASE ); - repo.addActiveReleaseScheme( ReleaseScheme.SNAPSHOT ); - StagingRepositoryFeature stagingFeat = repo.getFeature( StagingRepositoryFeature.class ).get( ); - stagingFeat.setStageRepoNeeded( true ); - IndexCreationFeature indexCreationFeature = repo.getFeature( IndexCreationFeature.class ).get(); - indexCreationFeature.setIndexPath( new URI("test/.indexes") ); - indexCreationFeature.setSkipPackedIndexCreation( true ); - ArtifactCleanupFeature artifactCleanupFeature = repo.getFeature( ArtifactCleanupFeature.class ).get(); - artifactCleanupFeature.setRetentionPeriod( Period.ofDays( 5 ) ); - artifactCleanupFeature.setRetentionCount( 7 ); - artifactCleanupFeature.setDeleteReleasedSnapshots( true ); - - ManagedRepositoryConfiguration cfg = provider.getManagedConfiguration( repo ); - assertEquals("target/this.is/a/test", cfg.getLocation()); - assertTrue(cfg.isScanned()); - assertEquals( "This is a description", cfg.getDescription() ); - assertEquals("maven2", cfg.getLayout()); - assertTrue(cfg.isBlockRedeployments()); - assertEquals("test0002", cfg.getName()); - assertEquals("0 0 05 ? * WED", cfg.getRefreshCronExpression()); - assertTrue(cfg.isStageRepoNeeded()); - assertEquals("test/.indexes", cfg.getIndexDir()); - assertTrue(cfg.isSkipPackedIndexCreation()); - assertEquals(5, cfg.getRetentionPeriod()); - assertEquals(7, cfg.getRetentionCount()); - assertTrue(cfg.isDeleteReleasedSnapshots()); - assertTrue(cfg.isReleases()); - assertTrue(cfg.isSnapshots()); - assertTrue(cfg.isScanned()); - - - - } - - @Test - public void getRemoteConfiguration() throws Exception { - MavenRemoteRepository repo = MavenRemoteRepository.newLocalInstance( "test01", "My Test repo", Paths.get("target/remotes") ); - - repo.setLocation( new URI("https://this.is/a/test") ); - repo.setScanned( true ); - repo.setDescription( repo.getPrimaryLocale(), "This is a description" ); - repo.setLayout( "maven2" ); - repo.setName( repo.getPrimaryLocale(), "test0003" ); - repo.setSchedulingDefinition( "0 0 05 ? * WED" ); - RemoteIndexFeature remoteIndexFeature = repo.getFeature( RemoteIndexFeature.class ).get(); - remoteIndexFeature.setProxyId( "proxyabc" ); - remoteIndexFeature.setDownloadTimeout( Duration.ofSeconds( 54 ) ); - remoteIndexFeature.setDownloadRemoteIndex( false ); - remoteIndexFeature.setIndexUri( new URI("/this/remote/.index") ); - remoteIndexFeature.setDownloadRemoteIndexOnStartup( true ); - IndexCreationFeature indexCreationFeature = repo.getFeature( IndexCreationFeature.class ).get(); - indexCreationFeature.setIndexPath( new URI("/this/local/.index") ); - - RemoteRepositoryConfiguration cfg = provider.getRemoteConfiguration( repo ); - assertEquals("https://this.is/a/test", cfg.getUrl()); - assertEquals( "This is a description", cfg.getDescription() ); - assertEquals("maven2", cfg.getLayout()); - assertEquals("test0003", cfg.getName()); - assertEquals("0 0 05 ? * WED", cfg.getRefreshCronExpression()); - assertEquals("/this/remote/.index", cfg.getRemoteIndexUrl()); - assertEquals("proxyabc", cfg.getRemoteDownloadNetworkProxyId()); - assertEquals(54, cfg.getRemoteDownloadTimeout()); - assertFalse(cfg.isDownloadRemoteIndex()); - assertTrue(cfg.isDownloadRemoteIndexOnStartup()); - assertEquals("/this/local/.index", cfg.getIndexDir()); - - - } - - @Test - public void getRepositoryGroupConfiguration() throws RepositoryException, URISyntaxException, IOException { - MavenRepositoryGroup repositoryGroup = MavenRepositoryGroup.newLocalInstance("group1","group1",Paths.get("target/groups")); - MavenManagedRepository repo1 = MavenManagedRepository.newLocalInstance( "test01", "My Test repo", Paths.get("target/repositories") ); - MavenManagedRepository repo2 = MavenManagedRepository.newLocalInstance( "test02", "My Test repo", Paths.get("target/repositories") ); - - - repositoryGroup.setDescription(repositoryGroup.getPrimaryLocale(), "Repository group"); - repositoryGroup.setLayout("non-default"); - IndexCreationFeature indexCreationFeature = repositoryGroup.getFeature( IndexCreationFeature.class ).get(); - indexCreationFeature.setIndexPath( new URI(".index2") ); - repositoryGroup.setName(repositoryGroup.getPrimaryLocale(), "Repo Group 1"); - repositoryGroup.setMergedIndexTTL(1005); - repositoryGroup.setSchedulingDefinition("0 0 04 ? * THU"); - repositoryGroup.addRepository(repo1); - repositoryGroup.addRepository(repo2); - - - RepositoryGroupConfiguration cfg = provider.getRepositoryGroupConfiguration(repositoryGroup); - assertEquals("group1", cfg.getId()); - assertEquals(".index2", cfg.getMergedIndexPath()); - assertEquals("0 0 04 ? * THU", cfg.getCronExpression()); - assertEquals("Repo Group 1", cfg.getName()); - assertEquals(1005, cfg.getMergedIndexTtl()); - assertTrue(cfg.getRepositories().contains("test01")); - assertTrue(cfg.getRepositories().contains("test02")); - assertEquals(2, cfg.getRepositories().size()); - } - - - @Test - public void createRepositoryGroup() { - EditableRepositoryGroup gr = provider.createRepositoryGroup("group1", "Group 1"); - assertEquals("group1",gr.getId()); - assertEquals("Group 1", gr.getName()); - assertEquals(MavenRepositoryGroup.class, gr.getClass()); - } - - @Test - public void createRepositoryGroupWithCfg() throws RepositoryException { - - RepositoryGroupConfiguration cfg = new RepositoryGroupConfiguration(); - cfg.setId("group2"); - cfg.setName("Group 2"); - cfg.setCronExpression("0 0 03 ? * MON"); - cfg.setMergedIndexTtl(504); - cfg.setMergedIndexPath(".index-abc"); - ArrayList repos = new ArrayList<>(); - repos.add("test01"); - repos.add("test02"); - cfg.setRepositories(repos); - - RepositoryGroup grp = provider.createRepositoryGroup(cfg); - - assertEquals("group2", grp.getId()); - assertEquals("Group 2", grp.getName()); - assertEquals("0 0 03 ? * MON", grp.getSchedulingDefinition()); - IndexCreationFeature indexCreationFeature = grp.getFeature( IndexCreationFeature.class ).get(); - try { - assertEquals(new URI(".index-abc"), indexCreationFeature.getIndexPath()); - } catch (URISyntaxException e) { - e.printStackTrace(); - } - assertEquals(504, grp.getMergedIndexTTL()); - assertEquals(0, grp.getRepositories().size()); - // assertTrue(grp.getRepositories().stream().anyMatch(r -> "test01".equals(r.getId()))); - // assertTrue(grp.getRepositories().stream().anyMatch(r -> "test02".equals(r.getId()))); - } - -} \ No newline at end of file diff --git a/archiva-modules/archiva-maven/archiva-maven-repository/src/test/java/org/apache/archiva/repository/maven/RepositoryURLTest.java b/archiva-modules/archiva-maven/archiva-maven-repository/src/test/java/org/apache/archiva/repository/maven/RepositoryURLTest.java deleted file mode 100644 index d1030975e..000000000 --- a/archiva-modules/archiva-maven/archiva-maven-repository/src/test/java/org/apache/archiva/repository/maven/RepositoryURLTest.java +++ /dev/null @@ -1,99 +0,0 @@ -package org.apache.archiva.repository.maven; - -/* - * 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.model.RepositoryURL; -import org.apache.archiva.test.utils.ArchivaBlockJUnit4ClassRunner; -import org.junit.Test; -import org.junit.runner.RunWith; - -import java.net.MalformedURLException; - -/** - * RepositoryURLTest - * - * - */ -@RunWith( ArchivaBlockJUnit4ClassRunner.class ) -public class RepositoryURLTest - extends TestCase -{ - private void assertURL( String actualURL, String protocol, String username, String password, String hostname, - String port, String path ) - { - RepositoryURL url = new RepositoryURL( actualURL ); - - assertEquals( protocol, url.getProtocol() ); - assertEquals( username, url.getUsername() ); - assertEquals( password, url.getPassword() ); - assertEquals( hostname, url.getHost() ); - assertEquals( port, url.getPort() ); - assertEquals( path, url.getPath() ); - } - - @Test - public void testProtocolHttp() - throws MalformedURLException - { - assertURL( "http://localhost/path/to/resource.txt", "http", null, null, "localhost", null, - "/path/to/resource.txt" ); - } - - @Test - public void testProtocolWagonWebdav() - throws MalformedURLException - { - assertURL( "dav:http://localhost/path/to/resource.txt", "dav:http", null, null, "localhost", null, - "/path/to/resource.txt" ); - } - - @Test - public void testProtocolHttpWithPort() - throws MalformedURLException - { - assertURL( "http://localhost:9090/path/to/resource.txt", "http", null, null, "localhost", "9090", - "/path/to/resource.txt" ); - } - - @Test - public void testProtocolHttpWithUsername() - throws MalformedURLException - { - assertURL( "http://user@localhost/path/to/resource.txt", "http", "user", null, "localhost", null, - "/path/to/resource.txt" ); - } - - @Test - public void testProtocolHttpWithUsernamePassword() - throws MalformedURLException - { - assertURL( "http://user:pass@localhost/path/to/resource.txt", "http", "user", "pass", "localhost", null, - "/path/to/resource.txt" ); - } - - @Test - public void testProtocolHttpWithUsernamePasswordPort() - throws MalformedURLException - { - assertURL( "http://user:pass@localhost:9090/path/to/resource.txt", "http", "user", "pass", "localhost", "9090", - "/path/to/resource.txt" ); - } -} diff --git a/archiva-modules/archiva-maven/archiva-maven-repository/src/test/java/org/apache/archiva/repository/maven/content/AbstractBaseRepositoryContentLayoutTest.java b/archiva-modules/archiva-maven/archiva-maven-repository/src/test/java/org/apache/archiva/repository/maven/content/AbstractBaseRepositoryContentLayoutTest.java deleted file mode 100644 index 519b2c251..000000000 --- a/archiva-modules/archiva-maven/archiva-maven-repository/src/test/java/org/apache/archiva/repository/maven/content/AbstractBaseRepositoryContentLayoutTest.java +++ /dev/null @@ -1,64 +0,0 @@ -package org.apache.archiva.repository.maven.content; - -/* - * 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.repository.content.BaseRepositoryContentLayout; -import org.apache.archiva.repository.content.ItemSelector; -import org.apache.archiva.repository.content.LayoutException; -import org.apache.archiva.repository.content.base.ArchivaItemSelector; -import org.junit.Test; - -import static org.junit.Assert.fail; - -/** - * Specific tests for ManagedRepositoryContent - * - * @author Martin Stockhammer - */ -public abstract class AbstractBaseRepositoryContentLayoutTest extends AbstractRepositoryContentTest -{ - - @Override - protected void assertBadPathCi( String path, String reason ) - { - super.assertBadPathCi( path, reason ); - try - { - getManaged().toItem( path ); - fail( - "toItem(path) should have thrown a LayoutException on the invalid path [" + path + "] because of [" + reason + "]" ); - } - catch ( LayoutException e ) - { - /* expected path */ - } - } - - @Test - public void testGetArtifactOnEmptyPath() throws LayoutException - { - ItemSelector selector = ArchivaItemSelector.builder( ).build( ); - try { - getManaged( ).getLayout( BaseRepositoryContentLayout.class ).getArtifact( selector ); - fail( "getArtifact(ItemSelector) with empty selector should throw IllegalArgumentException" ); - } catch (IllegalArgumentException e) { - // Good - } - } -} diff --git a/archiva-modules/archiva-maven/archiva-maven-repository/src/test/java/org/apache/archiva/repository/maven/content/AbstractRepositoryContentTest.java b/archiva-modules/archiva-maven/archiva-maven-repository/src/test/java/org/apache/archiva/repository/maven/content/AbstractRepositoryContentTest.java deleted file mode 100644 index 25c769bb1..000000000 --- a/archiva-modules/archiva-maven/archiva-maven-repository/src/test/java/org/apache/archiva/repository/maven/content/AbstractRepositoryContentTest.java +++ /dev/null @@ -1,682 +0,0 @@ -package org.apache.archiva.repository.maven.content; - -/* - * 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.repository.ManagedRepositoryContent; -import org.apache.archiva.repository.RepositoryContent; -import org.apache.archiva.repository.content.Artifact; -import org.apache.archiva.repository.content.BaseRepositoryContentLayout; -import org.apache.archiva.repository.content.ItemSelector; -import org.apache.archiva.repository.content.LayoutException; -import org.apache.archiva.repository.content.Namespace; -import org.apache.archiva.repository.content.Project; -import org.apache.archiva.repository.content.Version; -import org.apache.archiva.repository.content.base.ArchivaItemSelector; -import org.apache.archiva.repository.maven.AbstractRepositoryLayerTestCase; -import org.apache.commons.lang3.StringUtils; -import org.junit.Test; - -import static org.junit.Assert.*; - -/** - * AbstractDefaultRepositoryContentTestCase - */ -public abstract class AbstractRepositoryContentTest - extends AbstractRepositoryLayerTestCase -{ - @Test - public void testBadPathMissingType() - { - assertBadPath( "invalid/invalid/1/invalid-1", "missing type" ); - assertBadPathCi( "invalid/invalid/1/invalid-1", "missing type" ); - } - - @Test - public void testBadPathReleaseInSnapshotDir() - { - assertBadPath( "invalid/invalid/1.0-SNAPSHOT/invalid-1.0.jar", - "non snapshot artifact inside of a snapshot dir" ); - assertBadPathCi( "invalid/invalid/1.0-SNAPSHOT/invalid-1.0.jar", - "non snapshot artifact inside of a snapshot dir" ); - - } - - @Test - public void testBadPathTimestampedSnapshotNotInSnapshotDir() - { - assertBadPath( "invalid/invalid/1.0-20050611.123456-1/invalid-1.0-20050611.123456-1.jar", - "Timestamped Snapshot artifact not inside of an Snapshot dir" ); - assertBadPathCi( "invalid/invalid/1.0-20050611.123456-1/invalid-1.0-20050611.123456-1.jar", - "Timestamped Snapshot artifact not inside of an Snapshot dir" ); - } - - @Test - public void testBadPathTooShort() - { - assertBadPath( "invalid/invalid-1.0.jar", "path is too short" ); - assertBadPathCi( "invalid/invalid-1.0.jar", "path is too short" ); - } - - @Test - public void testBadPathVersionMismatchA() - { - assertBadPath( "invalid/invalid/1.0/invalid-2.0.jar", "version mismatch between path and artifact" ); - assertBadPathCi( "invalid/invalid/1.0/invalid-2.0.jar", "version mismatch between path and artifact" ); - } - - @Test - public void testBadPathVersionMismatchB() - { - assertBadPath( "invalid/invalid/1.0/invalid-1.0b.jar", "version mismatch between path and artifact" ); - assertBadPathCi( "invalid/invalid/1.0/invalid-1.0b.jar", "version mismatch between path and artifact" ); - } - - @Test - public void testBadPathWrongArtifactId() - { - assertBadPath( "org/apache/maven/test/1.0-SNAPSHOT/wrong-artifactId-1.0-20050611.112233-1.jar", - "wrong artifact id" ); - assertBadPathCi( "org/apache/maven/test/1.0-SNAPSHOT/wrong-artifactId-1.0-20050611.112233-1.jar", - "wrong artifact id" ); - } - - /** - * [MRM-432] Oddball version spec. - * Example of an oddball / unusual version spec. - * - * @throws LayoutException - * - */ - @Test - public void testGoodButOddVersionSpecGanymedSsh2() - throws LayoutException - { - String groupId = "ch.ethz.ganymed"; - String artifactId = "ganymed-ssh2"; - String version = "build210"; - String classifier = null; - String type = "jar"; - String path = "ch/ethz/ganymed/ganymed-ssh2/build210/ganymed-ssh2-build210.jar"; - - assertLayout( path, groupId, artifactId, version, classifier, type ); - assertLayoutCi( path, groupId, artifactId, version, classifier, type); - } - - /** - * [MRM-432] Oddball version spec. - * Example of an oddball / unusual version spec. - * - * @throws LayoutException - * - */ - @Test - public void testGoodButOddVersionSpecJavaxComm() - throws LayoutException - { - String groupId = "javax"; - String artifactId = "comm"; - String version = "3.0-u1"; - String classifier = null; - String type = "jar"; - String path = "javax/comm/3.0-u1/comm-3.0-u1.jar"; - - assertLayout( path, groupId, artifactId, version, classifier, type ); - assertLayoutCi( path, groupId, artifactId, version, classifier, type ); - } - - /** - * Test the ejb-client type spec. - * Type specs are not a 1 to 1 map to the extension. - * This tests that effect. - * @throws LayoutException - */ - /* TODO: Re-enabled in the future. - public void testGoodFooEjbClient() - throws LayoutException - { - String groupId = "com.foo"; - String artifactId = "foo-client"; - String version = "1.0"; - String classifier = null; - String type = "ejb-client"; // oddball type-spec (should result in jar extension) - String path = "com/foo/foo-client/1.0/foo-client-1.0.jar"; - - assertLayout( path, groupId, artifactId, version, classifier, type ); - } - */ - - /** - * [MRM-432] Oddball version spec. - * Example of an oddball / unusual version spec. - * - * @throws LayoutException - * - */ - @Test - public void testGoodButOddVersionSpecJavaxPersistence() - throws LayoutException - { - String groupId = "javax.persistence"; - String artifactId = "ejb"; - String version = "3.0-public_review"; - String classifier = null; - String type = "jar"; - String path = "javax/persistence/ejb/3.0-public_review/ejb-3.0-public_review.jar"; - - /* - * The version id of "public_review" can cause problems. is it part of - * the version spec? or the classifier? - * Since the path spec below shows it in the path, then it is really - * part of the version spec. - */ - - assertLayout( path, groupId, artifactId, version, classifier, type ); - assertLayoutCi( path, groupId, artifactId, version, classifier, type ); - } - - @Test - public void testGoodComFooTool() - throws LayoutException - { - String groupId = "com.foo"; - String artifactId = "foo-tool"; - String version = "1.0"; - String classifier = null; - String type = "jar"; - String path = "com/foo/foo-tool/1.0/foo-tool-1.0.jar"; - - assertLayout( path, groupId, artifactId, version, classifier, type ); - assertLayoutCi( path, groupId, artifactId, version, classifier, type ); - } - - @Test - public void testGoodCommonsLang() - throws LayoutException - { - String groupId = "commons-lang"; - String artifactId = "commons-lang"; - String version = "2.1"; - String classifier = null; - String type = "jar"; - String path = "commons-lang/commons-lang/2.1/commons-lang-2.1.jar"; - - assertLayout( path, groupId, artifactId, version, classifier, type ); - assertLayoutCi( path, groupId, artifactId, version, classifier, type ); - } - - /** - * [MRM-486] Can not deploy artifact test.maven-arch:test-arch due to "No ArtifactID Detected" - */ - @Test - public void testGoodDashedArtifactId() - throws LayoutException - { - String groupId = "test.maven-arch"; - String artifactId = "test-arch"; - String version = "2.0.3-SNAPSHOT"; - String classifier = null; - String type = "pom"; - String path = "test/maven-arch/test-arch/2.0.3-SNAPSHOT/test-arch-2.0.3-SNAPSHOT.pom"; - - assertLayout( path, groupId, artifactId, version, classifier, type ); - assertLayoutCi( path, groupId, artifactId, version, classifier, type ); - - } - - /** - * It may seem odd, but this is a valid artifact. - */ - @Test - public void testGoodDotNotationArtifactId() - throws LayoutException - { - String groupId = "com.company.department"; - String artifactId = "com.company.department"; - String version = "0.2"; - String classifier = null; - String type = "pom"; - String path = "com/company/department/com.company.department/0.2/com.company.department-0.2.pom"; - - assertLayout( path, groupId, artifactId, version, classifier, type ); - assertLayoutCi( path, groupId, artifactId, version, classifier, type ); - } - - /** - * It may seem odd, but this is a valid artifact. - */ - @Test - public void testGoodDotNotationSameGroupIdAndArtifactId() - throws LayoutException - { - String groupId = "com.company.department"; - String artifactId = "com.company.department.project"; - String version = "0.3"; - String classifier = null; - String type = "pom"; - String path = - "com/company/department/com.company.department.project/0.3/com.company.department.project-0.3.pom"; - - assertLayout( path, groupId, artifactId, version, classifier, type ); - assertLayoutCi( path, groupId, artifactId, version, classifier, type ); - - } - - /** - * Test the classifier, and java-source type spec. - * - * @throws LayoutException - * - */ - @Test - public void testGoodFooLibSources() - throws LayoutException - { - String groupId = "com.foo.lib"; - String artifactId = "foo-lib"; - String version = "2.1-alpha-1"; - String classifier = "sources"; - String type = "java-source"; // oddball type-spec (should result in jar extension) - String path = "com/foo/lib/foo-lib/2.1-alpha-1/foo-lib-2.1-alpha-1-sources.jar"; - - assertLayout( path, groupId, artifactId, version, classifier, type ); - assertLayoutCi( path, groupId, artifactId, version, classifier, type ); - - } - - /** - * A timestamped versioned artifact, should reside in a SNAPSHOT baseversion directory. - * - * @throws LayoutException - * - */ - @Test - public void testGoodSnapshotMavenTest() - throws LayoutException - { - String groupId = "org.apache.archiva.test"; - String artifactId = "redonkulous"; - String artifactVersion = "3.1-beta-1-20050831.101112-42"; - String version = "3.1-beta-1-SNAPSHOT"; - String classifier = null; - String type = "jar"; - String path = - "org/apache/archiva/test/redonkulous/3.1-beta-1-SNAPSHOT/redonkulous-3.1-beta-1-20050831.101112-42.jar"; - - assertLayout( path, groupId, artifactId, version, artifactVersion, classifier, type ); - assertLayoutCi( path, groupId, artifactId, version, artifactVersion, classifier, type ); - } - - /** - * [MRM-519] version identifiers within filename cause misidentification of version. - * Example uses "test" in artifact Id, which is also part of the versionKeyword list. - */ - @Test - public void testGoodVersionKeywordInArtifactId() - throws LayoutException - { - String groupId = "maven"; - String artifactId = "maven-test-plugin"; - String version = "1.8.2"; - String classifier = null; - String type = "pom"; - String path = "maven/maven-test-plugin/1.8.2/maven-test-plugin-1.8.2.pom"; - - assertLayout( path, groupId, artifactId, version, classifier, type ); - assertLayoutCi( path, groupId, artifactId, version, classifier, type ); - } - - /** - * [MRM-562] Artifact type "maven-plugin" is not detected correctly in .toArtifactReference() methods. - * Example uses "test" in artifact Id, which is also part of the versionKeyword list. - */ - @Test - public void testGoodDetectMavenTestPlugin() - throws LayoutException - { - String groupId = "maven"; - String artifactId = "maven-test-plugin"; - String version = "1.8.2"; - String classifier = null; - String type = "maven-plugin"; - String path = "maven/maven-test-plugin/1.8.2/maven-test-plugin-1.8.2.jar"; - - assertLayout( path, groupId, artifactId, version, classifier, type ); - assertLayoutCi( path, groupId, artifactId, version, classifier, type ); - - } - - /** - * [MRM-562] Artifact type "maven-plugin" is not detected correctly in .toArtifactReference() methods. - */ - @Test - public void testGoodDetectCoberturaMavenPlugin() - throws LayoutException - { - String groupId = "org.codehaus.mojo"; - String artifactId = "cobertura-maven-plugin"; - String version = "2.1"; - String classifier = null; - String type = "maven-plugin"; - String path = "org/codehaus/mojo/cobertura-maven-plugin/2.1/cobertura-maven-plugin-2.1.jar"; - - assertLayout( path, groupId, artifactId, version, classifier, type ); - assertLayoutCi( path, groupId, artifactId, version, classifier, type ); - } - - - @Test - public void testToItemSelectorOnEmptyPath() - { - try - { - getContent( ).toItemSelector( "" ); - fail( "toItemSelector() should have failed due to empty path." ); - } - catch ( LayoutException e ) - { - /* expected path */ - } - } - - @Test - public void testToArtifactOnEmptyPath() - { - try - { - toItemSelector( "" ); - fail( "Should have failed due to empty path." ); - } - catch ( LayoutException e ) - { - /* expected path */ - } - } - - @Test - public void testToArtifactOnNullPath() - { - try - { - toItemSelector( null ); - fail( "Should have failed due to null path." ); - } - catch ( LayoutException e ) - { - /* expected path */ - } - } - - @Test - public void testToItemSelectorOnNullPath() - { - try - { - getContent().toItemSelector( null ); - fail( "toItemSelector() should have failed due to null path." ); - } - catch ( LayoutException e ) - { - /* expected path */ - } - } - - @Test - public void testToPathOnNullArtifactReference() - - { - try - { - ItemSelector reference = null; - toPath( reference ); - fail( "Should have failed due to null artifact reference." ); - } - catch ( IllegalArgumentException e ) - { - /* expected path */ - } - } - - public void testToPathOnNullItemSelector() - - { - try - { - ItemSelector selector = null; - toPath( selector ); - fail( "Should have failed due to null artifact reference." ); - } - catch ( IllegalArgumentException e ) - { - /* expected path */ - } - } - - private void assertArtifactReference( ItemSelector actualReference, String groupId, String artifactId, - String version, String artifactVersion, String classifier, String type ) - { - String expectedId = - "ArtifactReference - " + groupId + ":" + artifactId + ":" + version + ":" + classifier + ":" + type; - - assertNotNull( expectedId + " - Should not be null.", actualReference ); - - assertEquals( expectedId + " - Group ID", groupId, actualReference.getNamespace() ); - assertEquals( expectedId + " - Artifact ID", artifactId, actualReference.getArtifactId() ); - if ( StringUtils.isNotBlank( classifier ) ) - { - assertEquals( expectedId + " - Classifier", classifier, actualReference.getClassifier() ); - } - assertEquals( expectedId + " - Version ID", version, actualReference.getVersion() ); - assertEquals( expectedId + " - Artifact Version ID", artifactVersion, actualReference.getArtifactVersion() ); - assertEquals( expectedId + " - Type", type, actualReference.getType() ); - } - - private void assertItemSelector( ItemSelector actualReference, String groupId, String artifactId, - String version, String artifactVersion, String classifier, String type ) - { - String expectedId = - "ArtifactReference - " + groupId + ":" + artifactId + ":" + version + ":" + classifier + ":" + type; - - assertNotNull( expectedId + " - Should not be null.", actualReference ); - - assertEquals( expectedId + " - Group ID", groupId, actualReference.getNamespace() ); - assertEquals( expectedId + " - Artifact ID", artifactId, actualReference.getArtifactId() ); - if ( StringUtils.isNotBlank( classifier ) ) - { - assertEquals( expectedId + " - Classifier", classifier, actualReference.getClassifier() ); - } - assertEquals( expectedId + " - Version ID", version, actualReference.getVersion() ); - assertEquals( expectedId + " - Artifact Version ID", artifactVersion, actualReference.getArtifactVersion() ); - assertEquals( expectedId + " - Type", type, actualReference.getType() ); - } - - private void assertBadPath( String path, String reason ) - { - try - { - toItemSelector( path ); - fail( - "Should have thrown a LayoutException on the invalid path [" + path + "] because of [" + reason + "]" ); - } - catch ( LayoutException e ) - { - /* expected path */ - } - } - - protected void assertBadPathCi( String path, String reason ) - { - try - { - toItemSelector( path ); - fail( - "Should have thrown a LayoutException on the invalid path [" + path + "] because of [" + reason + "]" ); - } - catch ( LayoutException e ) - { - /* expected path */ - } - } - - /** - * Perform a roundtrip through the layout routines to determine success. - */ - private void assertLayout( String path, String groupId, String artifactId, String version, String classifier, - String type ) - throws LayoutException - { - ItemSelector expectedArtifact = createItemSelector( groupId, artifactId, version, classifier, type ); - - // --- Artifact Tests. - - // Artifact to Path - assertEquals( "Artifact <" + expectedArtifact + "> to path:", path, toPath( expectedArtifact ) ); - - // --- Artifact Reference Tests - - // Path to Artifact Reference. - ItemSelector testReference = toItemSelector( path ); - assertArtifactReference( testReference, groupId, artifactId, version, version, classifier, type ); - - // And back again, using test Reference from previous step. - assertEquals( "Artifact <" + expectedArtifact + "> to path:", path, toPath( testReference ) ); - } - - /** - * Perform a roundtrip through the layout routines to determine success. - */ - private void assertLayout( String path, String groupId, String artifactId, String version, String artifactVersion, String classifier, - String type ) - throws LayoutException - { - ItemSelector expectedArtifact = createItemSelector( groupId, artifactId, version, artifactVersion, classifier, type ); - - // --- Artifact Tests. - - // Artifact to Path - assertEquals( "Artifact <" + expectedArtifact + "> to path:", path, toPath( expectedArtifact ) ); - - // --- Artifact Reference Tests - - // Path to Artifact Reference. - ItemSelector testReference = toItemSelector( path ); - assertArtifactReference( testReference, groupId, artifactId, version, artifactVersion, classifier, type ); - - // And back again, using test Reference from previous step. - assertEquals( "Artifact <" + expectedArtifact + "> to path:", path, toPath( testReference ) ); - } - - private void assertLayoutCi( String path, String groupId, String artifactId, String version, String classifier, - String type ) throws LayoutException - { - assertLayoutCi( path, groupId, artifactId, version, version, classifier, type ); - } - private void assertLayoutCi( String path, String groupId, String artifactId, String version, String artifactVersion, - String classifier, String type ) - throws LayoutException - { - ItemSelector expectedArtifact = createItemSelector( groupId, artifactId, version, artifactVersion, classifier, type ); - - // --- Artifact Tests. - - // Artifact to Path - assertEquals( "Artifact <" + expectedArtifact + "> to path:", path, toPath( expectedArtifact ) ); - - // --- Artifact Reference Tests - - // Path to Artifact Reference. - ItemSelector testReference = toItemSelector( path ); - assertItemSelector( testReference, groupId, artifactId, version, artifactVersion, classifier, type ); - - // And back again, using test Reference from previous step. - assertEquals( "Artifact <" + expectedArtifact + "> to path:", path, toPath( testReference ) ); - - if (getManaged()!=null) - { - Namespace ns = null; - Project pr = null; - Version ver = null; - if ( StringUtils.isNotEmpty( groupId ) ) - { - ns = getManaged( ).getLayout( BaseRepositoryContentLayout.class ).getNamespace( expectedArtifact ); - assertNotNull( ns ); - assertEquals( groupId, ns.getId( ) ); - } - if ( StringUtils.isNotEmpty( artifactId ) ) - { - pr = getManaged( ).getLayout( BaseRepositoryContentLayout.class ).getProject( expectedArtifact ); - assertNotNull( pr ); - assertEquals( artifactId, pr.getId( ) ); - assertEquals( ns, pr.getNamespace( ) ); - } - if ( StringUtils.isNotEmpty( version ) ) - { - ver = getManaged( ).getLayout( BaseRepositoryContentLayout.class ).getVersion( expectedArtifact ); - assertNotNull( ver ); - assertEquals( version, ver.getId( ) ); - assertEquals( pr, ver.getProject( ) ); - } - Artifact artifact = getManaged( ).getLayout( BaseRepositoryContentLayout.class ).getArtifact( expectedArtifact ); - assertNotNull( artifact ); - assertEquals( artifactId, artifact.getId( ) ); - assertEquals( ver, artifact.getVersion( ) ); - } - - } - - - abstract protected Artifact createArtifact( String groupId, String artifactId, String version, String classifier, - String type ) throws LayoutException; - - protected ItemSelector createItemSelector(String groupId, String artifactId, String version, String classifier, - String type) { - return ArchivaItemSelector.builder( ).withNamespace( groupId ) - .withProjectId( artifactId ) - .withArtifactId( artifactId ) - .withVersion( version ) - .withClassifier( classifier ) - .withType( type ) - .build( ); - - } - - protected ItemSelector createItemSelector(String groupId, String artifactId, String version, String artifactVersion, - String classifier, String type) { - return ArchivaItemSelector.builder( ).withNamespace( groupId ) - .withProjectId( artifactId ) - .withArtifactId( artifactId ) - .withVersion( version ) - .withArtifactVersion( artifactVersion ) - .withClassifier( classifier ) - .withType( type ) - .build( ); - - } - - - protected abstract String toPath( Artifact reference ) throws LayoutException; - - - protected abstract String toPath( ItemSelector selector ); - - protected abstract ItemSelector toItemSelector(String path) throws LayoutException; - - protected abstract ManagedRepositoryContent getManaged(); - - protected abstract RepositoryContent getContent( ); -} diff --git a/archiva-modules/archiva-maven/archiva-maven-repository/src/test/java/org/apache/archiva/repository/maven/content/ArtifactExtensionMappingTest.java b/archiva-modules/archiva-maven/archiva-maven-repository/src/test/java/org/apache/archiva/repository/maven/content/ArtifactExtensionMappingTest.java deleted file mode 100644 index 656c1c3eb..000000000 --- a/archiva-modules/archiva-maven/archiva-maven-repository/src/test/java/org/apache/archiva/repository/maven/content/ArtifactExtensionMappingTest.java +++ /dev/null @@ -1,82 +0,0 @@ -package org.apache.archiva.repository.maven.content; - -/* - * 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.maven.metadata.model.MavenArtifactFacet; -import org.apache.archiva.metadata.model.ArtifactMetadata; -import org.apache.archiva.metadata.repository.storage.RepositoryPathTranslator; -import org.apache.archiva.repository.maven.metadata.storage.ArtifactMappingProvider; -import org.apache.archiva.repository.maven.metadata.storage.Maven2RepositoryPathTranslator; -import org.apache.archiva.test.utils.ArchivaSpringJUnit4ClassRunner; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.springframework.test.context.ContextConfiguration; - -import java.util.Collections; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; - -/** - * ArtifactExtensionMappingTest - * - * - */ -@RunWith ( ArchivaSpringJUnit4ClassRunner.class ) -@ContextConfiguration ( { "classpath*:/META-INF/spring-context.xml", "classpath:/spring-context.xml" } ) -public class ArtifactExtensionMappingTest -{ - private RepositoryPathTranslator pathTranslator = new Maven2RepositoryPathTranslator( - Collections.emptyList() ); - - @Test - public void testIsMavenPlugin() - { - assertMavenPlugin( "maven-test-plugin" ); - assertMavenPlugin( "maven-clean-plugin" ); - assertMavenPlugin( "cobertura-maven-plugin" ); - assertMavenPlugin( "maven-project-info-reports-plugin" ); - assertMavenPlugin( "silly-name-for-a-maven-plugin" ); - - assertNotMavenPlugin( "maven-plugin-api" ); - assertNotMavenPlugin( "foo-lib" ); - assertNotMavenPlugin( "another-maven-plugin-api" ); - assertNotMavenPlugin( "secret-maven-plugin-2" ); - } - - private void assertMavenPlugin( String artifactId ) - { - assertEquals( "Should be detected as maven plugin: <" + artifactId + ">", "maven-plugin", getTypeFromArtifactId( - artifactId ) ); - } - - private String getTypeFromArtifactId( String artifactId ) - { - ArtifactMetadata artifact = pathTranslator.getArtifactFromId( null, "groupId", artifactId, "1.0", - artifactId + "-1.0.jar" ); - MavenArtifactFacet facet = (MavenArtifactFacet) artifact.getFacet( MavenArtifactFacet.FACET_ID ); - return facet.getType(); - } - - private void assertNotMavenPlugin( String artifactId ) - { - assertFalse( "Should NOT be detected as maven plugin: <" + artifactId + ">", "maven-plugin".equals( - getTypeFromArtifactId( artifactId ) ) ); - } -} diff --git a/archiva-modules/archiva-maven/archiva-maven-repository/src/test/java/org/apache/archiva/repository/maven/content/FilenameParserTest.java b/archiva-modules/archiva-maven/archiva-maven-repository/src/test/java/org/apache/archiva/repository/maven/content/FilenameParserTest.java deleted file mode 100644 index 1204d9670..000000000 --- a/archiva-modules/archiva-maven/archiva-maven-repository/src/test/java/org/apache/archiva/repository/maven/content/FilenameParserTest.java +++ /dev/null @@ -1,216 +0,0 @@ -package org.apache.archiva.repository.maven.content; - -/* - * 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.test.utils.ArchivaBlockJUnit4ClassRunner; -import org.junit.Test; -import org.junit.runner.RunWith; - -/** - * FilenameParserTest - * - * - */ -@RunWith( ArchivaBlockJUnit4ClassRunner.class ) -public class FilenameParserTest - extends TestCase -{ - @Test - public void testNameExtensionJar() - { - FilenameParser parser = new FilenameParser( "maven-test-plugin-1.8.3.jar" ); - - assertEquals( "maven-test-plugin-1.8.3", parser.getName() ); - assertEquals( "jar", parser.getExtension() ); - } - - @Test - public void testNameExtensionTarGz() - { - FilenameParser parser = new FilenameParser( "archiva-1.0-beta-2-bin.tar.gz" ); - - assertEquals( "archiva-1.0-beta-2-bin", parser.getName() ); - assertEquals( "tar.gz", parser.getExtension() ); - } - - @Test - public void testNameExtensionTarBz2() - { - FilenameParser parser = new FilenameParser( "archiva-1.0-SNAPSHOT-src.tar.bz2" ); - - assertEquals( "archiva-1.0-SNAPSHOT-src", parser.getName() ); - assertEquals( "tar.bz2", parser.getExtension() ); - } - - @Test - public void testNameExtensionCapitolizedTarGz() - { - FilenameParser parser = new FilenameParser( "ARCHIVA-1.0-BETA-2-BIN.TAR.GZ" ); - - assertEquals( "ARCHIVA-1.0-BETA-2-BIN", parser.getName() ); - assertEquals( "TAR.GZ", parser.getExtension() ); - } - - @Test - public void testNext() - { - FilenameParser parser = new FilenameParser( "maven-test-plugin-1.8.3.jar" ); - - assertEquals( "maven-test-plugin-1.8.3", parser.getName() ); - assertEquals( "jar", parser.getExtension() ); - - assertEquals( "maven", parser.next() ); - assertEquals( "test", parser.next() ); - assertEquals( "plugin", parser.next() ); - assertEquals( "1.8.3", parser.next() ); - assertNull( parser.next() ); - } - - @Test - public void testExpect() - { - FilenameParser parser = new FilenameParser( "maven-test-plugin-1.8.3.jar" ); - - assertEquals( "maven-test-plugin-1.8.3", parser.getName() ); - assertEquals( "jar", parser.getExtension() ); - - assertEquals( "maven-test-plugin", parser.expect( "maven-test-plugin" ) ); - assertEquals( "1.8.3", parser.expect( "1.8.3" ) ); - assertNull( parser.expect( "jar" ) ); - } - - @Test - public void testExpectWithRemaining() - { - FilenameParser parser = new FilenameParser( "ganymede-ssh2-build250-sources.jar" ); - - assertEquals( "ganymede-ssh2-build250-sources", parser.getName() ); - assertEquals( "jar", parser.getExtension() ); - - assertEquals( "ganymede-ssh2", parser.expect( "ganymede-ssh2" ) ); - assertEquals( "build250", parser.expect( "build250" ) ); - assertEquals( '-', parser.seperator() ); - assertEquals( "sources", parser.remaining() ); - - assertNull( parser.expect( "jar" ) ); - } - - @Test - public void testExpectWithRemainingDualExtensions() - { - FilenameParser parser = new FilenameParser( "example-presentation-3.2.xml.zip" ); - - assertEquals( "example-presentation-3.2.xml", parser.getName() ); - assertEquals( "zip", parser.getExtension() ); - - assertEquals( "example-presentation", parser.expect( "example-presentation" ) ); - assertEquals( "3.2", parser.expect( "3.2" ) ); - assertEquals( '.', parser.seperator() ); - assertEquals( "xml", parser.remaining() ); - - } - - @Test - public void testNextNonVersion() - { - FilenameParser parser = new FilenameParser( "maven-test-plugin-1.8.3.jar" ); - - assertEquals( "maven-test-plugin", parser.nextNonVersion() ); - assertEquals( "1.8.3", parser.remaining() ); - } - - @Test - public void testNextArbitraryNonVersion() - { - FilenameParser parser = new FilenameParser( "maven-jdk-1.4-plugin-1.0-20070828.123456-42.jar" ); - - assertEquals( "maven-jdk-1.4-plugin", parser.nextNonVersion() ); - assertEquals( "1.0-20070828.123456-42", parser.remaining() ); - } - - @Test - public void testNextJython() - { - FilenameParser parser = new FilenameParser( "jython-20020827-no-oro.jar" ); - - assertEquals( "jython", parser.nextNonVersion() ); - assertEquals( "20020827", parser.nextVersion() ); - assertEquals( "no-oro", parser.remaining() ); - } - - @Test - public void testLongExtension() - { - FilenameParser parser = new FilenameParser( "libfobs4jmf-0.4.1.4-20080217.211715-4.jnilib" ); - - assertEquals( "libfobs4jmf-0.4.1.4-20080217.211715-4", parser.getName() ); - assertEquals( "jnilib", parser.getExtension() ); - } - - @Test - public void testInterveningVersion() - { - FilenameParser parser = new FilenameParser( "artifact-id-1.0-abc-1.1-20080221.062205-9.pom" ); - - assertEquals( "artifact-id", parser.nextNonVersion() ); - assertEquals( "1.0-abc-1.1-20080221.062205-9", parser.expect( "1.0-abc-1.1-SNAPSHOT" ) ); - assertNull( null, parser.remaining() ); - assertEquals( "artifact-id-1.0-abc-1.1-20080221.062205-9", parser.getName() ); - assertEquals( "pom", parser.getExtension() ); - } - - @Test - public void testExpectWrongSnapshot() - { - FilenameParser parser = new FilenameParser( "artifact-id-1.0-20080221.062205-9.pom" ); - - assertEquals( "artifact-id", parser.nextNonVersion() ); - assertNull( parser.expect( "2.0-SNAPSHOT" ) ); - } - - @Test - public void testExpectWrongSnapshot2() - { - // tests parsing axiom snapshots without exceptions - FilenameParser parser = new FilenameParser( "axiom-20080221.062205-9.pom" ); - - assertEquals( "axiom", parser.nextNonVersion() ); - assertNull( parser.expect( "SNAPSHOT" ) ); - } - - @Test - public void testClassifier() - { - FilenameParser parser = new FilenameParser( "artifact-id-1.0-20070219.171202-34-test-sources.jar" ); - - assertEquals( "artifact-id", parser.nextNonVersion() ); - assertEquals( "1.0-20070219.171202-34", parser.nextVersion() ); - assertEquals( "test-sources", parser.remaining() ); - assertEquals( "artifact-id-1.0-20070219.171202-34-test-sources", parser.getName() ); - assertEquals( "jar", parser.getExtension() ); - } - - @Test - public void testNoExtension() - { - FilenameParser parser = new FilenameParser( "foo_bar" ); - assertNull( parser.getExtension() ); - } -} diff --git a/archiva-modules/archiva-maven/archiva-maven-repository/src/test/java/org/apache/archiva/repository/maven/content/ManagedDefaultRepositoryContentTest.java b/archiva-modules/archiva-maven/archiva-maven-repository/src/test/java/org/apache/archiva/repository/maven/content/ManagedDefaultRepositoryContentTest.java deleted file mode 100644 index 0b74e9dac..000000000 --- a/archiva-modules/archiva-maven/archiva-maven-repository/src/test/java/org/apache/archiva/repository/maven/content/ManagedDefaultRepositoryContentTest.java +++ /dev/null @@ -1,1507 +0,0 @@ -package org.apache.archiva.repository.maven.content; - -/* - * 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.filelock.FileLockManager; -import org.apache.archiva.common.utils.VersionComparator; -import org.apache.archiva.configuration.ArchivaConfiguration; -import org.apache.archiva.configuration.FileType; -import org.apache.archiva.configuration.FileTypes; -import org.apache.archiva.maven.metadata.MavenMetadataReader; -import org.apache.archiva.metadata.repository.storage.RepositoryPathTranslator; -import org.apache.archiva.repository.EditableManagedRepository; -import org.apache.archiva.repository.ManagedRepository; -import org.apache.archiva.repository.ManagedRepositoryContent; -import org.apache.archiva.repository.RepositoryContent; -import org.apache.archiva.repository.content.Artifact; -import org.apache.archiva.repository.content.BaseArtifactTypes; -import org.apache.archiva.repository.content.BaseRepositoryContentLayout; -import org.apache.archiva.repository.content.ContentItem; -import org.apache.archiva.repository.content.DataItem; -import org.apache.archiva.repository.content.ItemNotFoundException; -import org.apache.archiva.repository.content.ItemSelector; -import org.apache.archiva.repository.content.LayoutException; -import org.apache.archiva.repository.content.Namespace; -import org.apache.archiva.repository.content.Project; -import org.apache.archiva.repository.content.Version; -import org.apache.archiva.repository.content.base.ArchivaContentItem; -import org.apache.archiva.repository.content.base.ArchivaItemSelector; -import org.apache.archiva.repository.maven.MavenManagedRepository; -import org.apache.archiva.repository.maven.metadata.storage.ArtifactMappingProvider; -import org.apache.archiva.repository.storage.StorageAsset; -import org.apache.commons.io.FileUtils; -import org.junit.Before; -import org.junit.Test; - -import javax.inject.Inject; -import javax.inject.Named; -import java.io.IOException; -import java.io.OutputStream; -import java.io.Reader; -import java.net.URISyntaxException; -import java.nio.charset.Charset; -import java.nio.file.Files; -import java.nio.file.Path; -import java.nio.file.Paths; -import java.nio.file.attribute.FileTime; -import java.util.List; -import java.util.stream.Collectors; -import java.util.stream.Stream; - -import static org.junit.Assert.*; - -/** - * ManagedDefaultRepositoryContentTest - */ -public class ManagedDefaultRepositoryContentTest - extends AbstractBaseRepositoryContentLayoutTest -{ - private ManagedDefaultRepositoryContent repoContent; - - @Inject - FileTypes fileTypes; - - @Inject - @Named ( "archivaConfiguration#default" ) - ArchivaConfiguration archivaConfiguration; - - @Inject - List artifactMappingProviders; - - @Inject - MavenContentHelper contentHelper; - - @Inject - @Named( "metadataReader#maven" ) - MavenMetadataReader metadataReader; - - @Inject - FileLockManager fileLockManager; - - @Inject - @Named( "repositoryPathTranslator#maven2" ) - RepositoryPathTranslator pathTranslator; - - - private Path getRepositoryPath(String repoName) { - try - { - return Paths.get( Thread.currentThread( ).getContextClassLoader( ).getResource( "repositories/" + repoName ).toURI( ) ); - } - catch ( URISyntaxException e ) - { - throw new RuntimeException( "Could not resolve repository path " + e.getMessage( ), e ); - } - } - - @Before - public void setUp() - throws Exception - { - Path repoDir = getRepositoryPath( "default-repository" ); - - MavenManagedRepository repository = createRepository( "testRepo", "Unit Test Repo", repoDir ); - - FileType fileType = archivaConfiguration.getConfiguration().getRepositoryScanning().getFileTypes().get( 0 ); - fileType.addPattern( "**/*.xml" ); - assertEquals( FileTypes.ARTIFACTS, fileType.getId() ); - - fileTypes.afterConfigurationChange( null, "fileType", null ); - - repoContent = new ManagedDefaultRepositoryContent(repository, fileTypes, fileLockManager); - repoContent.setMavenContentHelper( contentHelper ); - repoContent.setMetadataReader( metadataReader ); - repoContent.setPathTranslator( pathTranslator ); - repoContent.setArtifactMappingProviders( artifactMappingProviders ); - - //repoContent = (ManagedRepositoryContent) lookup( ManagedRepositoryContent.class, "default" ); - } - - @Test - public void testGetVersionsSnapshotA() - throws Exception - { - assertArtifactVersions( "snap_shots_a", "1.0-alpha-11-SNAPSHOT", - new String[]{ "1.0-alpha-11-SNAPSHOT", "1.0-alpha-11-20070221.194724-2", - "1.0-alpha-11-20070302.212723-3", "1.0-alpha-11-20070303.152828-4", - "1.0-alpha-11-20070305.215149-5", "1.0-alpha-11-20070307.170909-6", - "1.0-alpha-11-20070314.211405-9", "1.0-alpha-11-20070316.175232-11" } ); - } - - - @Test - @Override - public void testToPathOnNullArtifactReference() - { - try - { - ItemSelector reference = null; - repoContent.toPath( reference ); - fail( "Should have failed due to null artifact reference." ); - } - catch ( IllegalArgumentException e ) - { - /* expected path */ - } - } - - @Override - protected Artifact createArtifact( String groupId, String artifactId, String version, String classifier, String type ) throws LayoutException - { - ItemSelector selector = createItemSelector( groupId, artifactId, version, classifier, type ); - return repoContent.getLayout( BaseRepositoryContentLayout.class ).getArtifact( selector ); - } - - @Test - public void testExcludeMetadataFile() - throws Exception - { - assertVersions( "include_xml", "1.0", new String[]{ "1.0" } ); - } - - - private void assertVersions( String artifactId, String version, String[] expectedVersions ) - throws Exception - { - // Use the test metadata-repository, which is already setup for - // These kind of version tests. - Path repoDir = getRepositoryPath( "metadata-repository" ); - ((EditableManagedRepository)repoContent.getRepository()).setLocation( repoDir.toAbsolutePath().toUri() ); - - // Request the versions. - - // Sort the list (for asserts later) - final VersionComparator comparator = new VersionComparator( ); - - ItemSelector selector = ArchivaItemSelector.builder( ) - .withNamespace( "org.apache.archiva.metadata.tests" ) - .withProjectId( artifactId ) - .withVersion( version ) - .build( ); - List versions = repoContent.getVersions( selector ).stream() - .map(v -> v.getId()).sorted( comparator ).collect( Collectors.toList()); - assertArrayEquals( expectedVersions, versions.toArray( ) ); - - - } - - private void assertArtifactVersions( String artifactId, String version, String[] expectedVersions ) - throws Exception - { - // Use the test metadata-repository, which is already setup for - // These kind of version tests. - Path repoDir = getRepositoryPath( "metadata-repository" ); - ((EditableManagedRepository)repoContent.getRepository()).setLocation( repoDir.toAbsolutePath().toUri() ); - - // Request the versions. - - // Sort the list (for asserts later) - final VersionComparator comparator = new VersionComparator( ); - - ItemSelector selector = ArchivaItemSelector.builder( ) - .withNamespace( "org.apache.archiva.metadata.tests" ) - .withProjectId( artifactId ) - .withVersion( version ) - .build( ); - List versions = repoContent.getArtifactVersions( selector ).stream() - .sorted( comparator ).collect( Collectors.toList()); - assertArrayEquals( expectedVersions, versions.toArray( ) ); - - - } - - @Test - public void getTestGetProjectWithIllegalArgs() { - ItemSelector selector = ArchivaItemSelector.builder( ) - .withNamespace( "org.apache" ) - .withVersion( "1.0" ) - .build(); - try - { - repoContent.getProject( selector ); - assertFalse( "Should throw IllegalArgumentException if no project id is given", true ); - } catch (IllegalArgumentException e) { - // Everything fine - assertTrue( e.getMessage( ).contains( "Project id must be set" ) ); - } - } - - @Test - public void getTestGetVersionWithIllegalArgs() { - ItemSelector selector = ArchivaItemSelector.builder( ) - .withNamespace( "org.apache.maven" ) - .withVersion( "1.0" ) - .build(); - try - { - repoContent.getVersion( selector ); - assertFalse( "Should throw IllegalArgumentException if no project id is given", true ); - } catch (IllegalArgumentException e) { - // Everything fine - assertTrue( e.getMessage( ).contains( "Project id must be set" ) ); - } - - - selector = ArchivaItemSelector.builder( ) - .withNamespace( "org.apache.maven" ) - .withProjectId( "shared" ) - .build(); - try - { - repoContent.getVersion( selector ); - assertFalse( "Should throw IllegalArgumentException if no version is given", true ); - } catch (IllegalArgumentException e) { - // Everything fine - assertTrue( e.getMessage( ).contains( "Version must be set" ) ); - } - } - - @Test - public void getTestGetArtifactWithIllegalArgs() { - ItemSelector selector = ArchivaItemSelector.builder( ) - .withNamespace( "org.apache.maven" ) - .withVersion( "1.0" ) - .withArtifactId( "shared" ) - .withArtifactVersion("1.0") - .build(); - try - { - repoContent.getArtifact( selector ); - assertFalse( "Should throw IllegalArgumentException if no project id is given", true ); - } catch (IllegalArgumentException e) { - // Everything fine - assertTrue( e.getMessage( ).contains( "Project id must be set" ) ); - } - - - selector = ArchivaItemSelector.builder( ) - .withNamespace( "org.apache.maven" ) - .withProjectId( "shared" ) - .withArtifactId( "shared" ) - .build(); - try - { - repoContent.getArtifact( selector ); - assertFalse( "Should throw IllegalArgumentException if no version is given", true ); - } catch (IllegalArgumentException e) { - // Everything fine - assertTrue( e.getMessage( ).contains( "Version must be set" ) ); - } - - selector = ArchivaItemSelector.builder( ) - .withNamespace( "org.apache.maven" ) - .withProjectId( "shared" ) - .withVersion("1.0") - .withArtifactVersion("1.0") - .build(); - try - { - repoContent.getArtifact( selector ); - assertFalse( "Should throw IllegalArgumentException if no artifact id is given", true ); - } catch (IllegalArgumentException e) { - // Everything fine - assertTrue( e.getMessage( ).contains( "Artifact id must be set" ) ); - } - - - } - - @Test - public void testGetProjects() { - ItemSelector selector = ArchivaItemSelector.builder( ) - .withNamespace( "org.apache.maven" ).build(); - Namespace ns = repoContent.getNamespace( selector ); - assertNotNull( ns ); - List projects = repoContent.getProjects( ns ); - assertEquals( 12, projects.size( ) ); - String[] expected = new String[]{ - "A", "B", "C", "archiva", "discovery", "maven-parent", "samplejar", "shared", "some-ejb", "test", - "testing", "update" - }; - Object[] actual = projects.stream( ).map( p -> p.getId( ) ).sorted( ).toArray( ); - assertArrayEquals( expected, actual); - } - - @Test - public void testGetProjectsWithSelector() { - ItemSelector selector = ArchivaItemSelector.builder( ) - .withNamespace( "org.apache.maven" ).build(); - List projects = repoContent.getProjects( selector ); - assertEquals( 12, projects.size( ) ); - String[] expected = new String[]{ - "A", "B", "C", "archiva", "discovery", "maven-parent", "samplejar", "shared", "some-ejb", "test", - "testing", "update" - }; - Object[] actual = projects.stream( ).map( p -> p.getId( ) ).sorted( ).toArray( ); - assertArrayEquals( expected, actual); - } - - @Test - public void testGetVersionsWithIllegalSelector() { - ItemSelector selector = ArchivaItemSelector.builder( ) - .withNamespace( "org.apache.maven" ).build(); - try - { - List versions = repoContent.getVersions( selector ); - assertFalse( "IllegalArgumentException expected, when project id not set", true ); - } catch (IllegalArgumentException e) { - assertEquals( "Project id not set, while retrieving versions.", e.getMessage( ) ); - } - } - - @Test - public void testGetVersionsWithSelector() { - ItemSelector selector = ArchivaItemSelector.builder( ) - .withNamespace( "org.apache.maven" ) - .withProjectId( "samplejar" ).build(); - List versions = repoContent.getVersions( selector ); - assertNotNull( versions ); - assertEquals( 2, versions.size( ) ); - } - - - @Override - protected ItemSelector toItemSelector( String path ) throws LayoutException - { - return repoContent.toItemSelector( path ); - } - - @Override - protected String toPath( Artifact reference ) - { - return repoContent.toPath( reference ); - } - - @Override - protected String toPath( ItemSelector selector ) { - return repoContent.toPath( selector ); - } - - @Override - protected ManagedRepositoryContent getManaged( ) - { - return repoContent; - } - - @Override - protected RepositoryContent getContent( ) - { - return repoContent; - } - - private Path setupRepoCopy( String source, String target) throws IOException - { - Path defaultRepo = getRepositoryPath( source ); - Path newRepo = defaultRepo.getParent( ).resolve( target ); - FileUtils.copyDirectory( defaultRepo.toFile( ), newRepo.toFile( ) ); - - MavenManagedRepository repository = createRepository( "testRepo", "Unit Test Repo", newRepo ); - - FileType fileType = archivaConfiguration.getConfiguration().getRepositoryScanning().getFileTypes().get( 0 ); - fileType.addPattern( "**/*.xml" ); - assertEquals( FileTypes.ARTIFACTS, fileType.getId() ); - - fileTypes.afterConfigurationChange( null, "fileType", null ); - - repoContent = new ManagedDefaultRepositoryContent(repository, fileTypes, fileLockManager); - return newRepo; - - } - - - @Test - public void testGetArtifactStreamWithVersionSelector() { - ItemSelector selector = ArchivaItemSelector.builder( ) - .withNamespace( "javax.sql" ) - .withProjectId( "jdbc" ) - .withVersion( "2.0" ).build(); - try(Stream stream = repoContent.newArtifactStream( selector )) - { - assertNotNull( stream ); - List results = stream.collect( Collectors.toList( ) ); - checkArtifactListWithVersionSelector1( results ); - } - } - - @Test - public void testGetArtifactListWithVersionSelector() { - ItemSelector selector = ArchivaItemSelector.builder( ) - .withNamespace( "javax.sql" ) - .withProjectId( "jdbc" ) - .withVersion( "2.0" ).build(); - List results = repoContent.getArtifacts( selector ); - checkArtifactListWithVersionSelector1( results ); - } - - private void checkArtifactListWithVersionSelector1( List results ) - { - assertNotNull( results ); - assertEquals( 2, results.size( ) ); - Artifact mainArtifact = results.stream( ).filter( a -> a.getFileName( ).equals( "jdbc-2.0.jar" ) ).findFirst( ).get( ); - assertNotNull( mainArtifact ); - assertEquals( BaseArtifactTypes.MAIN, mainArtifact.getDataType( ) ); - Artifact metaArtifact = results.stream( ).filter( a -> a.getFileName( ).equals( "maven-metadata-repository.xml" ) ).findFirst( ).get( ); - assertNotNull( metaArtifact ); - assertEquals( MavenTypes.REPOSITORY_METADATA, metaArtifact.getDataType( ) ); - } - - @Test - public void testGetArtifactStreamWithVersionSelector2() { - ItemSelector selector = ArchivaItemSelector.builder( ) - .withNamespace( "org.apache.axis2" ) - .withProjectId( "axis2" ) - .withVersion( "1.3-SNAPSHOT" ).build(); - try(Stream stream = repoContent.newArtifactStream( selector )) - { - assertNotNull( stream ); - List results = stream.collect( Collectors.toList( ) ); - checkArtifactListWithVersionSelector2( results ); - } - } - - @Test - public void testGetArtifactListWithVersionSelector2() { - ItemSelector selector = ArchivaItemSelector.builder( ) - .withNamespace( "org.apache.axis2" ) - .withProjectId( "axis2" ) - .withVersion( "1.3-SNAPSHOT" ).build(); - List results = repoContent.getArtifacts( selector ); - checkArtifactListWithVersionSelector2( results ); - } - - private void checkArtifactListWithVersionSelector2( List results ) - { - assertNotNull( results ); - assertEquals( 39, results.size( ) ); - - Artifact artifact = results.stream( ).filter( a -> a.getFileName( ).equals( "axis2-1.3-20070725.210059-1.pom" ) ) - .findFirst( ).get( ); - - assertNotNull( artifact ); - assertEquals( "pom", artifact.getExtension( ) ); - assertEquals( BaseArtifactTypes.MAIN, artifact.getDataType( ) ); - assertEquals( "1.3-SNAPSHOT", artifact.getVersion( ).getId( ) ); - assertEquals( "1.3-20070725.210059-1", artifact.getArtifactVersion( ) ); - assertEquals( ".pom", artifact.getRemainder( ) ); - assertEquals( "axis2", artifact.getId( ) ); - assertEquals( "axis2", artifact.getVersion( ).getProject( ).getId( ) ); - assertEquals( "org.apache.axis2", artifact.getVersion( ).getProject( ).getNamespace( ).getId( ) ); - assertEquals( "", artifact.getClassifier( ) ); - assertEquals( "pom", artifact.getType( ) ); - - artifact = null; - artifact = results.stream( ).filter( a -> a.getFileName( ).equals( "axis2-1.3-20070725.210059-1.pom.md5" ) ) - .findFirst( ).get( ); - - assertNotNull( artifact ); - assertEquals( "md5", artifact.getExtension( ) ); - assertEquals( BaseArtifactTypes.RELATED, artifact.getDataType( ) ); - assertEquals( "1.3-SNAPSHOT", artifact.getVersion( ).getId( ) ); - assertEquals( "1.3-20070725.210059-1", artifact.getArtifactVersion( ) ); - assertEquals( ".pom.md5", artifact.getRemainder( ) ); - assertEquals( "axis2", artifact.getId( ) ); - assertEquals( "axis2", artifact.getVersion( ).getProject( ).getId( ) ); - assertEquals( "org.apache.axis2", artifact.getVersion( ).getProject( ).getNamespace( ).getId( ) ); - assertEquals( "", artifact.getClassifier( ) ); - assertEquals( "md5", artifact.getType( ) ); - - - artifact = null; - artifact = results.stream( ).filter( a -> a.getFileName( ).equals( "maven-metadata.xml" ) ) - .findFirst( ).get( ); - assertNotNull( artifact ); - assertEquals( BaseArtifactTypes.METADATA, artifact.getDataType( ) ); - assertEquals( "1.3-SNAPSHOT", artifact.getVersion( ).getId( ) ); - assertEquals( "xml", artifact.getExtension( ) ); - } - - @Test - public void testGetArtifactListWithArtifactSelector1() { - ItemSelector selector = ArchivaItemSelector.builder( ) - .withNamespace( "org.apache.axis2" ) - .withProjectId( "axis2" ) - .withVersion( "1.3-SNAPSHOT" ) - .withArtifactVersion( "1.3-20070731.113304-21" ) - .withExtension( "pom" ) - .build( ); - List results = repoContent.getArtifacts( selector ); - checkArtifactListWithArtifactSelector1( results ); - } - - @Test - public void testGetArtifactStreamWithArtifactSelector1() { - ItemSelector selector = ArchivaItemSelector.builder( ) - .withNamespace( "org.apache.axis2" ) - .withProjectId( "axis2" ) - .withVersion( "1.3-SNAPSHOT" ) - .withArtifactVersion( "1.3-20070731.113304-21" ) - .withExtension( "pom" ) - .build( ); - try(Stream results = repoContent.newArtifactStream( selector )) - { - checkArtifactListWithArtifactSelector1( results.collect( Collectors.toList()) ); - } - } - - private void checkArtifactListWithArtifactSelector1( List results ) - { - assertNotNull( results ); - assertEquals( 1, results.size( ) ); - Artifact artifact = results.get( 0 ); - assertEquals( "pom", artifact.getExtension( ) ); - assertEquals( BaseArtifactTypes.MAIN, artifact.getDataType( ) ); - } - - @Test - public void testGetArtifactListWithArtifactSelector2() { - ItemSelector selector = ArchivaItemSelector.builder( ) - .withNamespace( "org.apache.axis2" ) - .withProjectId( "axis2" ) - .withVersion( "1.3-SNAPSHOT" ) - .withArtifactVersion( "1.3-20070731.113304-21" ) - .withExtension( "pom" ) - .includeRelatedArtifacts() - .build( ); - List results = repoContent.getArtifacts( selector ); - - checkArtifactListWithArtifactSelector2( results ); - - } - - @Test - public void testGetArtifactStreamWithArtifactSelector2() { - ItemSelector selector = ArchivaItemSelector.builder( ) - .withNamespace( "org.apache.axis2" ) - .withProjectId( "axis2" ) - .withVersion( "1.3-SNAPSHOT" ) - .withArtifactVersion( "1.3-20070731.113304-21" ) - .withExtension( "pom" ) - .includeRelatedArtifacts() - .build( ); - try(Stream results = repoContent.newArtifactStream( selector )) - { - checkArtifactListWithArtifactSelector2( results.collect( Collectors.toList()) ); - } - } - - private void checkArtifactListWithArtifactSelector2( List results ) - { - assertNotNull( results ); - assertEquals( 3, results.size( ) ); - Artifact artifact = results.stream( ).filter( a -> a.getFileName( ).equalsIgnoreCase( "axis2-1.3-20070731.113304-21.pom" ) ) - .findFirst( ).get( ); - assertNotNull( artifact ); - assertEquals( "pom", artifact.getExtension( ) ); - assertEquals( BaseArtifactTypes.MAIN, artifact.getDataType( ) ); - - artifact = results.stream( ).filter( a -> a.getFileName( ).equalsIgnoreCase( "axis2-1.3-20070731.113304-21.pom.sha1" ) ) - .findFirst( ).get( ); - assertNotNull( artifact ); - assertEquals( "sha1", artifact.getExtension( ) ); - assertEquals( BaseArtifactTypes.RELATED, artifact.getDataType( ) ); - } - - - @Test - public void testArtifactListWithProjectSelector() { - ItemSelector selector = ArchivaItemSelector.builder( ) - .withNamespace( "org.apache.maven.shared" ) - .withProjectId( "maven-downloader" ) - .build( ); - List results = repoContent.getArtifacts( selector ); - checkArtifactListWithProjectSelector( results ); - - } - - @Test - public void testArtifactStreamWithProjectSelector() { - ItemSelector selector = ArchivaItemSelector.builder( ) - .withNamespace( "org.apache.maven.shared" ) - .withProjectId( "maven-downloader" ) - .build( ); - Stream results = repoContent.newArtifactStream( selector ); - checkArtifactListWithProjectSelector( results.collect( Collectors.toList()) ); - - } - - private void checkArtifactListWithProjectSelector( List results ) - { - assertNotNull( results ); - assertEquals( 27, results.size( ) ); - - Artifact artifact = results.stream( ).filter( a -> a.getFileName( ).equalsIgnoreCase( "maven-metadata.xml" ) ) - .findFirst( ).get( ); - assertNotNull( artifact ); - assertEquals( "xml", artifact.getExtension( ) ); - assertEquals( BaseArtifactTypes.METADATA, artifact.getDataType( ) ); - - artifact = results.stream( ).filter( a -> a.getFileName( ).equalsIgnoreCase( "maven-downloader-1.0-sources.jar" ) ) - .findFirst( ).get( ); - assertNotNull( artifact ); - assertEquals( BaseArtifactTypes.MAIN, artifact.getDataType( ) ); - assertEquals( "sources", artifact.getClassifier( ) ); - assertEquals( "java-source", artifact.getType( ) ); - - artifact = results.stream( ).filter( a -> a.getFileName( ).equalsIgnoreCase( "maven-downloader-1.0-sources.jar.sha1" ) ) - .findFirst( ).get( ); - assertNotNull( artifact ); - assertEquals( BaseArtifactTypes.RELATED, artifact.getDataType( ) ); - assertEquals( "sources", artifact.getClassifier( ) ); - assertEquals( "sha1", artifact.getType( ) ); - assertEquals( ".jar.sha1", artifact.getRemainder( ) ); - } - - @Test - public void testArtifactListWithNamespaceSelector() { - ItemSelector selector = ArchivaItemSelector.builder( ) - .withNamespace( "org.multilevel" ) - .build( ); - List results = repoContent.getArtifacts( selector ); - assertNotNull( results ); - assertEquals( 3, results.size( ) ); - assertTrue( results.get( 0 ).getFileName( ).startsWith( "testproj1" ) ); - } - - @Test - public void testArtifactListWithNamespaceSelectorRecursive() { - ItemSelector selector = ArchivaItemSelector.builder( ) - .withNamespace( "org.multilevel" ) - .recurse() - .build( ); - List results = repoContent.getArtifacts( selector ); - checkArtifactListWithNamespaceSelectorRecursive( results ); - } - - @Test - public void testArtifactStreamWithNamespaceSelectorRecursive() { - ItemSelector selector = ArchivaItemSelector.builder( ) - .withNamespace( "org.multilevel" ) - .recurse() - .build( ); - Stream results = repoContent.newArtifactStream( selector ); - checkArtifactListWithNamespaceSelectorRecursive( results.collect( Collectors.toList()) ); - } - - private void checkArtifactListWithNamespaceSelectorRecursive( List results ) - { - assertNotNull( results ); - assertEquals( 6, results.size( ) ); - - Artifact artifact = results.stream( ).filter( a -> a.getFileName( ).equalsIgnoreCase( "testproj2-1.0.pom" ) ) - .findFirst( ).get( ); - assertNotNull( artifact ); - assertEquals( 6, artifact.getAsset( ).getParent( ).getPath( ).split( "/" ).length ); - - artifact = results.stream( ).filter( a -> a.getFileName( ).equalsIgnoreCase( "testproj1-1.0.pom" ) ) - .findFirst( ).get( ); - assertNotNull( artifact ); - assertEquals( 5, artifact.getAsset( ).getParent( ).getPath( ).split( "/" ).length ); - } - - - @Test - public void testArtifactListWithArtifactSelector1() { - ItemSelector selector = ArchivaItemSelector.builder( ) - .withNamespace( "org.apache.maven" ) - .withProjectId( "test" ) - .withVersion( "1.0-SNAPSHOT" ) - .withArtifactId( "test" ) - .withArtifactVersion( "1.0-20050611.112233-1" ) - .build( ); - - List results = repoContent.getArtifacts( selector ); - - assertNotNull( results ); - assertEquals( 1, results.size( ) ); - - Artifact artifact = results.stream( ).filter( a -> a.getFileName( ).equalsIgnoreCase( "test-1.0-20050611.112233-1.jar" ) ) - .findFirst().get(); - assertNotNull( artifact ); - assertEquals( "", artifact.getClassifier( ) ); - } - - @Test - public void testArtifactListWithArtifactSelector2() { - ItemSelector selector = ArchivaItemSelector.builder( ) - .withNamespace( "org.apache.maven" ) - .withProjectId( "test" ) - .withVersion( "1.0-SNAPSHOT" ) - .withClassifier( "*" ) - .withArtifactId( "test" ) - .withArtifactVersion( "1.0-20050611.112233-1" ) - .build( ); - - List results = repoContent.getArtifacts( selector ); - - assertNotNull( results ); - assertEquals( 2, results.size( ) ); - - Artifact artifact = results.stream( ).filter( a -> a.getFileName( ).equalsIgnoreCase( "test-1.0-20050611.112233-1-javadoc.jar" ) ) - .findFirst().get(); - assertNotNull( artifact ); - assertEquals( "javadoc", artifact.getClassifier( ) ); - assertEquals( "javadoc", artifact.getType( ) ); - } - - @Test - public void testArtifactListWithArtifactSelector3() { - ItemSelector selector = ArchivaItemSelector.builder( ) - .withNamespace( "org.apache.maven" ) - .withProjectId( "test" ) - .withVersion( "1.0-SNAPSHOT" ) - .withClassifier( "*" ) - .withArtifactVersion( "1.0-20050611.112233-1" ) - .build( ); - - List results = repoContent.getArtifacts( selector ); - - assertNotNull( results ); - assertEquals( 3, results.size( ) ); - - Artifact artifact = results.stream( ).filter( a -> a.getFileName( ).equalsIgnoreCase( "test-1.0-20050611.112233-1-javadoc.jar" ) ) - .findFirst().get(); - assertNotNull( artifact ); - assertEquals( "javadoc", artifact.getClassifier( ) ); - assertEquals( "javadoc", artifact.getType( ) ); - - artifact = results.stream( ).filter( a -> a.getFileName( ).equalsIgnoreCase( "wrong-artifactId-1.0-20050611.112233-1.jar" ) ) - .findFirst().get(); - assertNotNull( artifact ); - assertEquals( "", artifact.getClassifier( ) ); - assertEquals( "wrong-artifactId", artifact.getId( ) ); - } - - @Test - public void testArtifactListWithArtifactSelector4() { - ItemSelector selector = ArchivaItemSelector.builder( ) - .withNamespace( "org.apache.maven" ) - .withProjectId( "test" ) - .withVersion( "1.0-SNAPSHOT" ) - .withClassifier( "" ) - .build( ); - - List results = repoContent.getArtifacts( selector ); - - assertNotNull( results ); - assertEquals( 5, results.size( ) ); - - Artifact artifact = results.stream( ).filter( a -> a.getFileName( ).equalsIgnoreCase( "test-1.0-20050611.112233-1-javadoc.jar" ) ) - .findFirst().get(); - assertNotNull( artifact ); - assertEquals( "javadoc", artifact.getClassifier( ) ); - assertEquals( "javadoc", artifact.getType( ) ); - - artifact = results.stream( ).filter( a -> a.getFileName( ).equalsIgnoreCase( "wrong-artifactId-1.0-20050611.112233-1.jar" ) ) - .findFirst().get(); - assertNotNull( artifact ); - assertEquals( "", artifact.getClassifier( ) ); - assertEquals( "wrong-artifactId", artifact.getId( ) ); - - artifact = results.stream( ).filter( a -> a.getFileName( ).equalsIgnoreCase( "wrong-artifactId-1.0-20050611.1122x-1.jar" ) ) - .findFirst().get(); - assertNotNull( artifact ); - assertEquals( "", artifact.getClassifier( ) ); - assertEquals( "wrong-artifactId", artifact.getId( ) ); - assertEquals( "", artifact.getArtifactVersion( ) ); - - artifact = results.stream( ).filter( a -> a.getFileName( ).equalsIgnoreCase( "test-1.0-20050611.1122x-1.jar" ) ) - .findFirst().get(); - assertNotNull( artifact ); - assertEquals( "", artifact.getClassifier( ) ); - assertEquals( "test", artifact.getId( ) ); - assertEquals( "1.0-20050611.1122x-1", artifact.getArtifactVersion( ) ); - - } - - @Test - public void testArtifactListWithArtifactSelectorWithClassifier() { - ItemSelector selector = ArchivaItemSelector.builder( ) - .withNamespace( "org.apache.maven" ) - .withProjectId( "test" ) - .withVersion( "1.0-SNAPSHOT" ) - .withArtifactId( "test" ) - .withClassifier( "javadoc" ) - .withArtifactVersion( "1.0-20050611.112233-1" ) - .build( ); - - List results = repoContent.getArtifacts( selector ); - - assertNotNull( results ); - assertEquals( 1, results.size( ) ); - - Artifact artifact = results.stream( ).filter( a -> a.getFileName( ).equalsIgnoreCase( "test-1.0-20050611.112233-1-javadoc.jar" ) ) - .findFirst().get(); - assertNotNull( artifact ); - assertEquals( "javadoc", artifact.getClassifier( ) ); - assertEquals( "javadoc", artifact.getType( ) ); - } - - @Test - public void testArtifactListWithArtifactSelectorWrongArtifact() { - ItemSelector selector = ArchivaItemSelector.builder( ) - .withNamespace( "org.apache.maven" ) - .withProjectId( "test" ) - .withVersion( "1.0-SNAPSHOT" ) - .withArtifactId( "wrong-artifactId" ) - .withArtifactVersion( "1.0-20050611.112233-1" ) - .build( ); - - List results = repoContent.getArtifacts( selector ); - - assertNotNull( results ); - assertEquals( 1, results.size( ) ); - - Artifact artifact = results.stream( ).filter( a -> a.getFileName( ).equalsIgnoreCase( "wrong-artifactId-1.0-20050611.112233-1.jar" ) ) - .findFirst().get(); - assertNotNull( artifact ); - } - - @Test - public void testArtifactListWithArtifactSelectorVersionPattern() { - ItemSelector selector = ArchivaItemSelector.builder( ) - .withNamespace( "org.apache.maven" ) - .withProjectId( "test" ) - .withVersion( "1.0-SNAPSHOT" ) - .withArtifactVersion( "1.0-*" ) - .build( ); - - List results = repoContent.getArtifacts( selector ); - - assertNotNull( results ); - assertEquals( 5, results.size( ) ); - - Artifact artifact = results.stream( ).filter( a -> a.getFileName( ).equalsIgnoreCase( "wrong-artifactId-1.0-20050611.112233-1.jar" ) ) - .findFirst().get(); - assertNotNull( artifact ); - } - - - @Test - public void testNewItemStreamWithNamespace1() { - ItemSelector selector = ArchivaItemSelector.builder( ) - .withNamespace( "org.apache.axis2" ) - .build(); - - Stream stream = repoContent.newItemStream( selector, false ); - List result = stream.collect( Collectors.toList( ) ); - assertEquals( 41, result.size( ) ); - ContentItem item = result.get( 39 ); - Version version = item.adapt( Version.class ); - assertNotNull( version ); - assertEquals( "1.3-SNAPSHOT", version.getId( ) ); - Project project = result.get( 40 ).adapt( Project.class ); - assertNotNull( project ); - assertEquals( "axis2", project.getId( ) ); - assertTrue( result.stream( ).anyMatch( a -> "axis2-1.3-20070725.210059-1.pom".equals( a.getAsset( ).getName( ) ) ) ); - } - - @Test - public void testNewItemStreamWithNamespace2() { - ItemSelector selector = ArchivaItemSelector.builder( ) - .withNamespace( "org.apache.maven" ) - .recurse() - .build(); - - Stream stream = repoContent.newItemStream( selector, false ); - List result = stream.collect( Collectors.toList( ) ); - assertEquals( 170, result.size( ) ); - assertEquals( 92, result.stream( ).filter( a -> a instanceof DataItem ).count( ) ); - } - - @Test - public void testGetArtifactFromContentItem() { - ItemSelector selector = ArchivaItemSelector.builder( ) - .withNamespace( "org.apache.maven" ).build(); - Namespace ns = repoContent.getNamespace( selector ); - List artifacts = repoContent.getArtifacts( ns ); - assertNotNull( artifacts ); - assertEquals( 39, artifacts.size( ) ); - List artifacts2 = repoContent.getArtifacts( (ContentItem)ns ); - assertArrayEquals( artifacts.toArray(), artifacts2.toArray() ); - - selector = ArchivaItemSelector.builder( ) - .withNamespace( "org.apache.maven.shared" ) - .withProjectId( "maven-downloader" ) - .build(); - Project project = repoContent.getProject( selector ); - artifacts = repoContent.getArtifacts( project ); - assertNotNull( artifacts ); - assertEquals( 27, artifacts.size( ) ); - artifacts2 = repoContent.getArtifacts( (ContentItem)project ); - assertArrayEquals( artifacts.toArray(), artifacts2.toArray() ); - - selector = ArchivaItemSelector.builder( ) - .withNamespace( "org.apache.maven.shared" ) - .withProjectId( "maven-downloader" ) - .withVersion( "1.1" ) - .build( ); - Version version = repoContent.getVersion( selector ); - artifacts = repoContent.getArtifacts( version ); - assertNotNull( artifacts ); - assertEquals( 12, artifacts.size( ) ); - artifacts2 = repoContent.getArtifacts( (ContentItem)version ); - assertArrayEquals( artifacts.toArray(), artifacts2.toArray() ); - - } - - @Test - public void testGetRelatedArtifactsFromArtifact() { - ItemSelector selector = ArchivaItemSelector.builder( ) - .withNamespace( "org.apache.maven.shared" ) - .withProjectId( "maven-downloader" ) - .withVersion( "1.1" ) - .withExtension( "jar" ) - .withArtifactId( "maven-downloader" ).build( ); - - Artifact artifact = repoContent.getArtifact( selector ); - assertNotNull( artifact ); - List artifacts = repoContent.getArtifacts( artifact ); - assertNotNull( artifacts ); - assertEquals( 2, artifacts.size( ) ); - - } - - @Test - public void testToItemFromPath() throws LayoutException - { - String path = "/org/apache/maven/shared"; - ContentItem item = repoContent.toItem( path ); - assertNotNull( item ); - assertTrue( item instanceof ArchivaContentItem ); - - path = "/org/apache/maven/shared/maven-downloader"; - item = repoContent.toItem( path ); - assertNotNull( item ); - assertTrue( item instanceof ArchivaContentItem ); - - path = "/org/apache/maven/shared/maven-downloader/1.1"; - item = repoContent.toItem( path ); - assertNotNull( item ); - assertTrue( item instanceof ArchivaContentItem ); - - path = "/org/apache/maven/shared/maven-downloader/1.1/maven-downloader-1.1.jar"; - item = repoContent.toItem( path ); - assertNotNull( item ); - assertTrue( item instanceof DataItem ); - - } - - @Test - public void testToItemFromAssetPath() throws LayoutException - { - StorageAsset path = repoContent.getRepository().getAsset("/org/apache/maven/shared"); - ContentItem item = repoContent.toItem( path ); - assertNotNull( item ); - assertTrue( item instanceof ArchivaContentItem ); - - path = repoContent.getRepository( ).getAsset( "/org/apache/maven/shared/maven-downloader" ); - item = repoContent.toItem( path ); - assertNotNull( item ); - assertTrue( item instanceof ArchivaContentItem ); - - path = repoContent.getRepository( ).getAsset( "/org/apache/maven/shared/maven-downloader/1.1" ); - item = repoContent.toItem( path ); - assertNotNull( item ); - assertTrue( item instanceof ArchivaContentItem ); - - path = repoContent.getRepository( ).getAsset( "/org/apache/maven/shared/maven-downloader/1.1/maven-downloader-1.1.jar" ); - item = repoContent.toItem( path ); - assertNotNull( item ); - assertTrue( item instanceof DataItem ); - - } - - @Test - public void testHasContent() throws LayoutException - { - ItemSelector selector = ArchivaItemSelector.builder( ) - .withNamespace( "org.apache.maven.shared" ) - .withProjectId( "maven-downloader" ) - .withVersion( "1.1" ) - .withArtifactId( "maven-downloader" ) - .withExtension( "jar" ) - .build(); - - assertTrue( repoContent.hasContent( selector ) ); - - selector = ArchivaItemSelector.builder( ) - .withNamespace( "org.apache.maven.shared" ) - .withProjectId( "maven-downloader" ) - .withVersion( "1.1" ) - .withArtifactId( "maven-downloader" ) - .withExtension( "zip" ) - .build(); - - assertFalse( repoContent.hasContent( selector ) ); - - } - - @Test - public void testGetItemWithNamespaceSelector() { - ItemSelector selector = ArchivaItemSelector.builder( ) - .withNamespace( "org.apache.maven" ) - .build( ); - ContentItem item = repoContent.getItem( selector ); - assertNotNull( item ); - assertTrue( item instanceof Namespace ); - } - - @Test - public void testGetItemWithProjectSelector() { - ItemSelector selector = ArchivaItemSelector.builder( ) - .withNamespace( "org.apache.maven" ) - .withProjectId( "shared" ) - .build( ); - ContentItem item = repoContent.getItem( selector ); - assertNotNull( item ); - assertTrue( item instanceof Project ); - } - - @Test - public void testGetItemWithVersionSelector() { - ItemSelector selector = ArchivaItemSelector.builder( ) - .withNamespace( "org.apache.maven" ) - .withProjectId( "samplejar" ) - .withVersion("2.0") - .build( ); - ContentItem item = repoContent.getItem( selector ); - assertNotNull( item ); - assertTrue( item instanceof Version ); - } - - @Test - public void testGetItemWithArtifactSelector() { - ItemSelector selector = ArchivaItemSelector.builder( ) - .withNamespace( "org.apache.maven" ) - .withProjectId( "samplejar" ) - .withVersion("2.0") - .withArtifactId( "samplejar" ) - .build( ); - ContentItem item = repoContent.getItem( selector ); - assertNotNull( item ); - assertTrue( item instanceof Artifact ); - } - - @Test - public void testGetNamespaceFromPath() throws LayoutException - { - StorageAsset path = repoContent.getRepository( ).getAsset( "/org/apache/axis2" ); - Namespace ns = repoContent.getNamespaceFromPath( path ); - assertNotNull( ns ); - assertEquals( "org.apache.axis2", ns.getId( ) ); - - } - - @Test - public void testArtifactListWithArtifactSelectorAndRelated() { - ItemSelector selector = ArchivaItemSelector.builder( ) - .withNamespace( "org.apache.maven" ) - .withProjectId( "samplejar" ) - .withVersion( "1.0" ) - .withArtifactVersion( "1.0" ) - .withArtifactId( "samplejar" ) - .withExtension( "jar" ) - .includeRelatedArtifacts() - .build( ); - - List results = repoContent.getArtifacts( selector ); - - assertNotNull( results ); - assertEquals( 3, results.size( ) ); - - Artifact artifact = results.stream( ).filter( a -> a.getFileName( ).equalsIgnoreCase( "samplejar-1.0.jar" ) ) - .findFirst().get(); - assertNotNull( artifact ); - assertEquals( BaseArtifactTypes.MAIN, artifact.getDataType( ) ); - - artifact = results.stream( ).filter( a -> a.getFileName( ).equalsIgnoreCase( "samplejar-1.0.jar.md5" ) ) - .findFirst().get(); - assertNotNull( artifact ); - assertEquals( BaseArtifactTypes.RELATED, artifact.getDataType( ) ); - assertEquals( "md5", artifact.getExtension( ) ); - - artifact = results.stream( ).filter( a -> a.getFileName( ).equalsIgnoreCase( "samplejar-1.0.jar.sha1" ) ) - .findFirst().get(); - assertNotNull( artifact ); - assertEquals( BaseArtifactTypes.RELATED, artifact.getDataType( ) ); - assertEquals( "sha1", artifact.getExtension( ) ); - - } - - private Path copyRepository(String repoName) throws IOException, URISyntaxException - { - Path tempDir = Files.createTempDirectory( "archiva-repocontent" ); - Path repoSource = Paths.get( Thread.currentThread( ).getContextClassLoader( ).getResource( "repositories/" + repoName ).toURI( ) ); - assertTrue( Files.exists( repoSource ) ); - FileUtils.copyDirectory( repoSource.toFile( ), tempDir.toFile() ); - return tempDir; - } - - private ManagedRepository createManagedRepoWithContent(String sourceRepoName) throws IOException, URISyntaxException - { - Path repoDir = copyRepository( sourceRepoName ); - MavenManagedRepository repo = createRepository( sourceRepoName, sourceRepoName, repoDir ); - ManagedDefaultRepositoryContent deleteRepoContent = new ManagedDefaultRepositoryContent( repo, fileTypes, fileLockManager ); - deleteRepoContent.setMavenContentHelper( contentHelper ); - return repo; - } - - @Test - public void deleteNamespaceItem() throws IOException, URISyntaxException, ItemNotFoundException - { - ManagedRepository repo = createManagedRepoWithContent( "delete-repository" ); - ManagedRepositoryContent myRepoContent = repo.getContent( ); - Path repoRoot = repo.getRoot().getFilePath( ); - assertTrue( Files.exists(repoRoot.resolve( "org/apache/maven" )) ); - ArchivaItemSelector selector = ArchivaItemSelector.builder( ) - .withNamespace( "org.apache.maven" ).build(); - ContentItem item = myRepoContent.getItem( selector ); - assertTrue( item instanceof Namespace ); - myRepoContent.deleteItem( item ); - assertFalse( Files.exists(repoRoot.resolve( "org/apache/maven" )) ); - assertTrue( Files.exists(repoRoot.resolve( "org/apache" )) ); - - // Sub namespaces are deleted too - assertTrue( Files.exists(repoRoot.resolve( "org/apache/test/samplejar" )) ); - assertTrue( Files.exists(repoRoot.resolve( "org/apache/test/sub/samplejar" )) ); - selector = ArchivaItemSelector.builder( ) - .withNamespace( "org.apache.test" ).build(); - item = myRepoContent.getItem( selector ); - assertTrue( item instanceof Namespace ); - myRepoContent.deleteItem( item ); - assertFalse( Files.exists(repoRoot.resolve( "org/apache/test/samplejar" )) ); - assertFalse( Files.exists(repoRoot.resolve( "org/apache/test/sub/samplejar" )) ); - } - - @Test - public void deleteProjectItem() throws IOException, URISyntaxException, ItemNotFoundException - { - ManagedRepository repo = createManagedRepoWithContent( "delete-repository" ); - ManagedRepositoryContent myRepoContent = repo.getContent( ); - Path repoRoot = repo.getRoot().getFilePath( ); - assertTrue( Files.exists(repoRoot.resolve( "org/apache/maven/A" )) ); - ArchivaItemSelector selector = ArchivaItemSelector.builder( ) - .withNamespace( "org.apache.maven" ) - .withProjectId( "A" ).build(); - ContentItem item = myRepoContent.getItem( selector ); - assertTrue( item instanceof Project ); - myRepoContent.deleteItem( item ); - assertTrue( Files.exists(repoRoot.resolve( "org/apache/maven" )) ); - assertTrue( Files.exists( repoRoot.resolve( "org/apache/maven/samplejar/1.0" ) ) ); - assertTrue( Files.exists( repoRoot.resolve( "org/apache/maven/samplejar/2.0" ) ) ); - assertFalse( Files.exists(repoRoot.resolve( "org/apache/maven/A" )) ); - - assertTrue( Files.exists(repoRoot.resolve( "org/apache/test/samplejar" )) ); - assertTrue( Files.exists(repoRoot.resolve( "org/apache/test/sub/samplejar" )) ); - selector = ArchivaItemSelector.builder( ) - .withNamespace( "org.apache.test" ) - .withProjectId( "samplejar" ).build(); - item = myRepoContent.getItem( selector ); - assertTrue( item instanceof Project ); - myRepoContent.deleteItem( item ); - assertFalse( Files.exists(repoRoot.resolve( "org/apache/test/samplejar" )) ); - assertTrue( Files.exists(repoRoot.resolve( "org/apache/test/sub/samplejar" )) ); - } - - @Test - public void deleteVersionItem() throws IOException, URISyntaxException, ItemNotFoundException - { - ManagedRepository repo = createManagedRepoWithContent( "delete-repository" ); - ManagedRepositoryContent myRepoContent = repo.getContent( ); - Path repoRoot = repo.getRoot().getFilePath( ); - assertTrue( Files.exists(repoRoot.resolve( "org/apache/maven/A/1.0" )) ); - ArchivaItemSelector selector = ArchivaItemSelector.builder( ) - .withNamespace( "org.apache.maven" ) - .withProjectId( "A" ) - .withVersion( "1.0" ).build(); - ContentItem item = myRepoContent.getItem( selector ); - assertTrue( item instanceof Version ); - myRepoContent.deleteItem( item ); - assertTrue( Files.exists(repoRoot.resolve( "org/apache/maven/A" )) ); - assertTrue( Files.exists( repoRoot.resolve( "org/apache/maven/samplejar/1.0" ) ) ); - assertTrue( Files.exists( repoRoot.resolve( "org/apache/maven/samplejar/2.0" ) ) ); - assertFalse( Files.exists(repoRoot.resolve( "org/apache/maven/A/1.0" )) ); - - assertTrue( Files.exists(repoRoot.resolve( "org/apache/test/samplejar" )) ); - assertTrue( Files.exists(repoRoot.resolve( "org/apache/test/sub/samplejar" )) ); - selector = ArchivaItemSelector.builder( ) - .withNamespace( "org.apache.test" ) - .withProjectId( "samplejar" ) - .withVersion( "2.0" ).build(); - item = myRepoContent.getItem( selector ); - assertTrue( item instanceof Version ); - myRepoContent.deleteItem( item ); - assertFalse( Files.exists(repoRoot.resolve( "org/apache/test/samplejar/2.0" )) ); - assertTrue( Files.exists(repoRoot.resolve( "org/apache/test/samplejar/1.0" )) ); - assertTrue( Files.exists(repoRoot.resolve( "org/apache/test/sub/samplejar/1.0" )) ); - assertTrue( Files.exists(repoRoot.resolve( "org/apache/test/sub/samplejar/2.0" )) ); - } - - @Test - public void deleteArtifactItem() throws IOException, URISyntaxException, ItemNotFoundException - { - ManagedRepository repo = createManagedRepoWithContent( "delete-repository" ); - ManagedRepositoryContent myRepoContent = repo.getContent( ); - Path repoRoot = repo.getRoot().getFilePath( ); - assertTrue( Files.exists(repoRoot.resolve( "org/apache/maven/A/1.0/A-1.0.pom" )) ); - assertTrue( Files.exists(repoRoot.resolve( "org/apache/maven/A/1.0/A-1.0.war" )) ); - ArchivaItemSelector selector = ArchivaItemSelector.builder( ) - .withNamespace( "org.apache.maven" ) - .withProjectId( "A" ) - .withVersion( "1.0" ) - .withArtifactId( "A" ) - .withArtifactVersion( "1.0" ) - .withExtension( "pom" ) - .build(); - ContentItem item = myRepoContent.getItem( selector ); - assertTrue( item instanceof Artifact ); - myRepoContent.deleteItem( item ); - assertTrue( Files.exists( repoRoot.resolve( "org/apache/maven/samplejar/1.0" ) ) ); - assertTrue( Files.exists( repoRoot.resolve( "org/apache/maven/samplejar/2.0" ) ) ); - assertFalse( Files.exists(repoRoot.resolve( "org/apache/maven/A/1.0/A-1.0.pom" )) ); - assertTrue( Files.exists(repoRoot.resolve( "org/apache/maven/A/1.0/A-1.0.war" )) ); - - - assertTrue( Files.exists(repoRoot.resolve( "org/apache/test/samplejar/1.0/samplejar-1.0.jar" )) ); - assertTrue( Files.exists(repoRoot.resolve( "org/apache/test/samplejar/1.0/samplejar-1.0.jar.md5" )) ); - assertTrue( Files.exists(repoRoot.resolve( "org/apache/test/samplejar/1.0/samplejar-1.0.jar.sha1" )) ); - assertTrue( Files.exists(repoRoot.resolve( "org/apache/test/samplejar/1.0/samplejar-1.0.pom" )) ); - assertTrue( Files.exists(repoRoot.resolve( "org/apache/test/samplejar/1.0/samplejar-1.0-source.jar" )) ); - selector = ArchivaItemSelector.builder( ) - .withNamespace( "org.apache.test" ) - .withProjectId( "samplejar" ) - .withVersion( "1.0" ) - .withArtifactId( "samplejar" ) - .withArtifactVersion( "1.0" ) - .withExtension( "jar" ) - .build(); - item = myRepoContent.getItem( selector ); - assertTrue( item instanceof Artifact ); - myRepoContent.deleteItem( item ); - assertFalse( Files.exists(repoRoot.resolve( "org/apache/test/samplejar/1.0/samplejar-1.0.jar" )) ); - assertTrue( Files.exists(repoRoot.resolve( "org/apache/test/samplejar/1.0/samplejar-1.0.jar.md5" )) ); - assertTrue( Files.exists(repoRoot.resolve( "org/apache/test/samplejar/1.0/samplejar-1.0.jar.sha1" )) ); - assertTrue( Files.exists(repoRoot.resolve( "org/apache/test/samplejar/1.0/samplejar-1.0.pom" )) ); - assertTrue( Files.exists(repoRoot.resolve( "org/apache/test/samplejar/1.0/samplejar-1.0-source.jar" )) ); - assertTrue( Files.exists(repoRoot.resolve( "org/apache/test/samplejar/2.0" )) ); - assertTrue( Files.exists(repoRoot.resolve( "org/apache/test/sub/samplejar/1.0" )) ); - assertTrue( Files.exists(repoRoot.resolve( "org/apache/test/sub/samplejar/2.0" )) ); - - selector = ArchivaItemSelector.builder( ) - .withNamespace( "org.apache.test" ) - .withProjectId( "samplejar" ) - .withVersion( "1.0" ) - .withArtifactId( "samplejar" ) - .withArtifactVersion( "1.0" ) - .withClassifier( "source" ) - .withExtension( "jar" ) - .build(); - item = myRepoContent.getItem( selector ); - assertTrue( item instanceof Artifact ); - myRepoContent.deleteItem( item ); - assertFalse( Files.exists(repoRoot.resolve( "org/apache/test/samplejar/1.0/samplejar-1.0.jar" )) ); - assertTrue( Files.exists(repoRoot.resolve( "org/apache/test/samplejar/1.0/samplejar-1.0.jar.md5" )) ); - assertTrue( Files.exists(repoRoot.resolve( "org/apache/test/samplejar/1.0/samplejar-1.0.jar.sha1" )) ); - assertTrue( Files.exists(repoRoot.resolve( "org/apache/test/samplejar/1.0/samplejar-1.0.pom" )) ); - assertFalse( Files.exists(repoRoot.resolve( "org/apache/test/samplejar/1.0/samplejar-1.0-source.jar" )) ); - assertTrue( Files.exists(repoRoot.resolve( "org/apache/test/samplejar/1.0/samplejar-1.0-source.jar.sha1" )) ); - assertTrue( Files.exists(repoRoot.resolve( "org/apache/test/samplejar/2.0" )) ); - assertTrue( Files.exists(repoRoot.resolve( "org/apache/test/sub/samplejar/1.0" )) ); - assertTrue( Files.exists(repoRoot.resolve( "org/apache/test/sub/samplejar/2.0" )) ); - - selector = ArchivaItemSelector.builder( ) - .withNamespace( "org.apache.test" ) - .withProjectId( "samplejar" ) - .withVersion( "1.0" ) - .withArtifactId( "samplejar" ) - .withArtifactVersion( "1.0" ) - .withExtension( "jar.md5" ) - .build(); - item = myRepoContent.getItem( selector ); - assertTrue( item instanceof Artifact ); - myRepoContent.deleteItem( item ); - assertFalse( Files.exists(repoRoot.resolve( "org/apache/test/samplejar/1.0/samplejar-1.0.jar" )) ); - assertFalse( Files.exists(repoRoot.resolve( "org/apache/test/samplejar/1.0/samplejar-1.0.jar.md5" )) ); - assertTrue( Files.exists(repoRoot.resolve( "org/apache/test/samplejar/1.0/samplejar-1.0.jar.sha1" )) ); - assertTrue( Files.exists(repoRoot.resolve( "org/apache/test/samplejar/1.0/samplejar-1.0.pom" )) ); - assertFalse( Files.exists(repoRoot.resolve( "org/apache/test/samplejar/1.0/samplejar-1.0-source.jar" )) ); - assertTrue( Files.exists(repoRoot.resolve( "org/apache/test/samplejar/1.0/samplejar-1.0-source.jar.sha1" )) ); - assertTrue( Files.exists(repoRoot.resolve( "org/apache/test/samplejar/2.0" )) ); - assertTrue( Files.exists(repoRoot.resolve( "org/apache/test/sub/samplejar/1.0" )) ); - assertTrue( Files.exists(repoRoot.resolve( "org/apache/test/sub/samplejar/2.0" )) ); - - - } - - @Test - public void deleteItemNotFound() throws IOException, URISyntaxException, ItemNotFoundException - { - ManagedRepository repo = createManagedRepoWithContent( "delete-repository" ); - ManagedRepositoryContent myRepoContent = repo.getContent( ); - Path repoRoot = repo.getRoot().getFilePath( ); - - ArchivaItemSelector selector = ArchivaItemSelector.builder( ) - .withNamespace( "org.apache.test2" ) - .build( ); - - ContentItem item = myRepoContent.getItem( selector ); - assertTrue( item instanceof Namespace ); - try - { - myRepoContent.deleteItem( item ); - assertTrue( "ItemNotFoundException expected for non existing namespace", false ); - } catch ( ItemNotFoundException e) { - } - - selector = ArchivaItemSelector.builder( ) - .withNamespace( "org.apache.test" ) - .withProjectId( "samplejar2" ) - .build( ); - item = myRepoContent.getItem( selector ); - assertTrue( item instanceof Project ); - try - { - myRepoContent.deleteItem( item ); - assertTrue( "ItemNotFoundException expected for non existing project", false ); - } catch ( ItemNotFoundException e) { - } - - selector = ArchivaItemSelector.builder( ) - .withNamespace( "org.apache.test" ) - .withProjectId( "samplejar" ) - .withVersion("1.1") - .build( ); - item = myRepoContent.getItem( selector ); - assertTrue( item instanceof Version ); - try - { - myRepoContent.deleteItem( item ); - assertTrue( "ItemNotFoundException expected for non existing version", false ); - } catch ( ItemNotFoundException e) { - } - - selector = ArchivaItemSelector.builder( ) - .withNamespace( "org.apache.test" ) - .withProjectId( "samplejar" ) - .withVersion("1.0") - .withArtifactId( "samplejar" ) - .withArtifactVersion( "1.0" ) - .withExtension( "jax" ) - .build( ); - item = myRepoContent.getItem( selector ); - assertTrue( item instanceof Artifact ); - try - { - myRepoContent.deleteItem( item ); - assertTrue( "ItemNotFoundException expected for non existing artifact", false ); - } catch ( ItemNotFoundException e) { - } - - } - - - @Test - public void testAddArtifact() throws IOException, URISyntaxException, LayoutException - { - ManagedRepository repo = createManagedRepoWithContent( "delete-repository" ); - ManagedRepositoryContent myRepoContent = repo.getContent( ); - BaseRepositoryContentLayout layout = myRepoContent.getLayout( BaseRepositoryContentLayout.class ); - Path repoRoot = repo.getRoot().getFilePath( ); - - Path tmpFile = Files.createTempFile( "archiva-mvn-repotest", "jar" ); - try( OutputStream outputStream = Files.newOutputStream( tmpFile )) - { - for ( int i = 0; i < 255; i++ ) - { - outputStream.write( "test.test.test\n".getBytes( Charset.forName( "UTF-8" ) ) ); - } - } - - Path file = repoRoot.resolve( "org/apache/maven/samplejar/2.0/samplejar-2.0.jar" ); - FileTime lmt = Files.getLastModifiedTime( file ); - ArchivaItemSelector selector = ArchivaItemSelector.builder( ) - .withNamespace( "org.apache.maven" ) - .withProjectId( "samplejar" ) - .withVersion( "2.0" ) - .withArtifactId( "samplejar" ) - .withArtifactVersion( "2.0" ) - .withExtension( "jar" ) - .build( ); - Artifact artifact = layout.getArtifact( selector ); - layout.addArtifact( tmpFile, artifact ); - FileTime lmtAfter = Files.getLastModifiedTime( file ); - assertNotEquals( lmtAfter, lmt ); - Reader ln = Files.newBufferedReader( file, Charset.forName( "UTF-8" ) ); - char[] content = new char[50]; - ln.read( content ); - assertTrue( new String( content ).startsWith( "test.test.test" ) ); - - tmpFile = Files.createTempFile( "archiva-mvn-repotest", "jar" ); - try( OutputStream outputStream = Files.newOutputStream( tmpFile )) - { - for ( int i = 0; i < 255; i++ ) - { - outputStream.write( "test.test.test\n".getBytes( Charset.forName( "UTF-8" ) ) ); - } - } - file = repoRoot.resolve( "org/apache/maven/samplejar/2.0/samplejar-2.0.test" ); - assertFalse( Files.exists( file ) ); - assertTrue( Files.exists( tmpFile ) ); - selector = ArchivaItemSelector.builder( ) - .withNamespace( "org.apache.maven" ) - .withProjectId( "samplejar" ) - .withVersion( "2.0" ) - .withArtifactId( "samplejar" ) - .withArtifactVersion( "2.0" ) - .withExtension( "test" ) - .build( ); - artifact = layout.getArtifact( selector ); - layout.addArtifact( tmpFile, artifact ); - ln = Files.newBufferedReader( file, Charset.forName( "UTF-8" ) ); - ln.read( content ); - assertTrue( new String( content ).startsWith( "test.test.test" ) ); - } - - @Test - public void getExistingMetadataItem() { - // org/apache/maven/some-ejb/1.0 - ArchivaItemSelector versionSelector = ArchivaItemSelector.builder( ) - .withNamespace( "org.apache.maven" ) - .withProjectId( "some-ejb" ) - .withVersion( "1.0" ).build( ); - Version version = repoContent.getVersion( versionSelector ); - DataItem metaData = repoContent.getMetadataItem( version ); - assertTrue( metaData.exists( ) ); - assertEquals( "/org/apache/maven/some-ejb/1.0/maven-metadata.xml", metaData.getAsset( ).getPath( ) ); - } - - @Test - public void getNonExistingMetadataItem() { - // org/apache/maven/some-ejb/1.0 - ArchivaItemSelector versionSelector = ArchivaItemSelector.builder( ) - .withNamespace( "javax.sql" ) - .withProjectId( "jdbc" ) - .withVersion( "2.0" ).build( ); - Version version = repoContent.getVersion( versionSelector ); - DataItem metaData = repoContent.getMetadataItem( version ); - assertFalse( metaData.exists( ) ); - assertEquals( "/javax/sql/jdbc/2.0/maven-metadata.xml", metaData.getAsset( ).getPath( ) ); - } - -} diff --git a/archiva-modules/archiva-maven/archiva-maven-repository/src/test/java/org/apache/archiva/repository/maven/content/MavenContentHelperTest.java b/archiva-modules/archiva-maven/archiva-maven-repository/src/test/java/org/apache/archiva/repository/maven/content/MavenContentHelperTest.java deleted file mode 100644 index 0de06b838..000000000 --- a/archiva-modules/archiva-maven/archiva-maven-repository/src/test/java/org/apache/archiva/repository/maven/content/MavenContentHelperTest.java +++ /dev/null @@ -1,209 +0,0 @@ -package org.apache.archiva.repository.maven.content; - -/* - * 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.filelock.DefaultFileLockManager; -import org.apache.archiva.maven.metadata.MavenMetadataReader; -import org.apache.archiva.repository.content.ItemSelector; -import org.apache.archiva.repository.content.base.ArchivaItemSelector; -import org.apache.archiva.repository.storage.StorageAsset; -import org.apache.archiva.repository.storage.fs.FilesystemStorage; -import org.junit.jupiter.api.AfterAll; -import org.junit.jupiter.api.BeforeAll; -import org.junit.jupiter.api.Test; - -import java.io.IOException; -import java.net.URISyntaxException; -import java.nio.file.Files; -import java.nio.file.Path; -import java.nio.file.Paths; - -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertNotNull; - -/** - * @author Martin Stockhammer - */ -class MavenContentHelperTest -{ - - private static FilesystemStorage storage; - private static Path tempDir; - - @BeforeAll - static void setUp() throws IOException - { - tempDir = Files.createTempDirectory( "archivamaventest" ); - storage = new FilesystemStorage( tempDir, new DefaultFileLockManager() ); - } - - @AfterAll - static void tearDown() { - try - { - Files.deleteIfExists( tempDir ); - } - catch ( IOException e ) - { - System.err.println( "Could not delete " + tempDir ); - } - } - - @Test - void getNamespaceFromNamespacePath( ) - { - StorageAsset asset = storage.getAsset( "org/apache/archiva" ); - String ns = MavenContentHelper.getNamespaceFromNamespacePath( asset ); - assertNotNull( ns ); - assertEquals( "org.apache.archiva", ns ); - - asset = storage.getRoot(); - ns = MavenContentHelper.getNamespaceFromNamespacePath( asset ); - assertNotNull( ns ); - assertEquals( "", ns ); - } - - @Test - void getArtifactVersion( ) throws IOException, URISyntaxException - { - MavenContentHelper mavenContentHelper = new MavenContentHelper( ); - MavenMetadataReader reader = new MavenMetadataReader( ); - mavenContentHelper.setMetadataReader( reader ); - Path testRepoPath = Paths.get( Thread.currentThread( ).getContextClassLoader( ).getResource( "repositories/metadata-repository" ).toURI() ); - FilesystemStorage storage = new FilesystemStorage( testRepoPath, new DefaultFileLockManager( ) ); - assertArtifactVersion( mavenContentHelper, "1.0-alpha-11-SNAPSHOT", storage.getAsset( "org/apache/archiva/metadata/tests/snap_shots_1/1.0-alpha-11-SNAPSHOT" ) - , "1.0-alpha-11-SNAPSHOT", "1.0-alpha-11-SNAPSHOT"); - - assertArtifactVersion( mavenContentHelper, "1.0-alpha-11-20070316.175232-11", storage.getAsset( "org/apache/archiva/metadata/tests/snap_shots_a/1.0-alpha-11-SNAPSHOT" ) - , "", "1.0-alpha-11-SNAPSHOT"); - - assertArtifactVersion( mavenContentHelper, "2.2-20070316.153953-10", storage.getAsset( "org/apache/archiva/metadata/tests/snap_shots_b/2.2-SNAPSHOT" ) - , "", "2.2-SNAPSHOT"); - - } - - private void assertArtifactVersion(MavenContentHelper mavenContentHelper, String expectedVersion, StorageAsset dir, String selectorArtifactVersion, String selectorVersion) { - ItemSelector selector = ArchivaItemSelector.builder( ) - .withVersion( selectorVersion ) - .withArtifactVersion( selectorArtifactVersion ) - .build( ); - assertEquals( expectedVersion, mavenContentHelper.getArtifactVersion( dir, selector ) ); - } - - @Test - void getLatestArtifactSnapshotVersion( ) throws URISyntaxException, IOException - { - MavenContentHelper mavenContentHelper = new MavenContentHelper( ); - MavenMetadataReader reader = new MavenMetadataReader( ); - mavenContentHelper.setMetadataReader( reader ); - Path testRepoPath = Paths.get( Thread.currentThread( ).getContextClassLoader( ).getResource( "repositories/default-repository" ).toURI() ); - FilesystemStorage storage = new FilesystemStorage( testRepoPath, new DefaultFileLockManager( ) ); - // Directory without metadata file - assertEquals( "2.1-20090808.085535-2", mavenContentHelper.getLatestArtifactSnapshotVersion( storage.getAsset( "org/apache/archiva/sample-parent/2.1-SNAPSHOT" ), "2.1-SNAPSHOT" ) ); - // Directory with metadata file - assertEquals( "1.3-20070802.113139-29", mavenContentHelper.getLatestArtifactSnapshotVersion( storage.getAsset( "org/apache/axis2/axis2/1.3-SNAPSHOT" ), "1.3-SNAPSHOT" ) ); - } - - @Test - void getArtifactFileName( ) - { - assertFileName( "test-1.0.jar", "test", "", "1.0", "jar" ); - assertFileName( "test-1.1-client.jar", "test", "client", "1.1", "jar" ); - assertFileName( "te445st-2.1-sources.jar", "te445st", "sources", "2.1", "jar" ); - assertFileName( "abcde-8888.994894.48484-10.jar", "abcde", "", "8888.994894.48484-10", "jar" ); - assertFileName( "testarchive-5.0.war", "testarchive", "", "5.0", "war" ); - } - - private void assertFileName(String expectedFilename, String artifactId, String classifier, String version, String extension) { - assertEquals( expectedFilename, MavenContentHelper.getArtifactFileName( artifactId, version, classifier, extension ) ); - } - - @Test - void getClassifier( ) - { - assertClassifier( "sources", "","java-source" ); - assertClassifier( "tests", "", "test-jar" ); - assertClassifier( "client", "","ejb-client" ); - assertClassifier( "javadoc", "","javadoc" ); - assertClassifier( "", "","test" ); - assertClassifier( "test1", "test1","java-source" ); - assertClassifier( "test2", "test2", "test-jar" ); - assertClassifier( "test3", "test3","ejb-client" ); - assertClassifier( "test4", "test4","javadoc" ); - assertClassifier( "test5", "test5","test" ); - } - private void assertClassifier(String expectedClassifier, String classifier, String type) { - ItemSelector selector = ArchivaItemSelector.builder( ) - .withClassifier( classifier ) - .withType( type ).build(); - assertEquals( expectedClassifier, MavenContentHelper.getClassifier( selector ) ); - } - - @Test - void getClassifierFromType( ) - { - assertClassifier( "sources", "java-source" ); - assertClassifier( "tests", "test-jar" ); - assertClassifier( "client", "ejb-client" ); - assertClassifier( "javadoc", "javadoc" ); - assertClassifier( "", "test" ); - } - - private void assertClassifier(String expectedClassifier, String type) { - assertEquals( expectedClassifier, MavenContentHelper.getClassifierFromType( type ) ); - } - - @Test - void getTypeFromClassifierAndExtension( ) - { - assertType( "javadoc", "javadoc", "jar" ); - assertType( "war", "", "war" ); - assertType( "ear", "", "ear" ); - assertType( "rar", "", "rar" ); - assertType( "java-source", "sources", "jar" ); - assertType( "ejb-client", "client", "jar" ); - assertType( "pom", "", "pom" ); - assertType( "test-jar", "tests", "jar" ); - - } - - private void assertType(String expectedType, String classifier, String extension) { - assertEquals( expectedType, MavenContentHelper.getTypeFromClassifierAndExtension( classifier, extension ) ); - } - - - - @Test - void getArtifactExtension( ) - { - assertExtension( "test", "", "test" ); - assertExtension( "jar", "javadoc", "" ); - assertExtension( "war", "war", "" ); - assertExtension( "ear", "ear", "" ); - assertExtension( "rar", "rar", "" ); - assertExtension( "jar", "", "" ); - } - - private void assertExtension( String expectedExtension, String type, String extension ) - { - ItemSelector selector = ArchivaItemSelector.builder( ) - .withType( type ).withExtension( extension ).build(); - assertEquals( expectedExtension, MavenContentHelper.getArtifactExtension( selector ) ); - } -} \ No newline at end of file diff --git a/archiva-modules/archiva-maven/archiva-maven-repository/src/test/java/org/apache/archiva/repository/maven/content/MavenRepositoryRequestInfoTest.java b/archiva-modules/archiva-maven/archiva-maven-repository/src/test/java/org/apache/archiva/repository/maven/content/MavenRepositoryRequestInfoTest.java deleted file mode 100644 index 784ce4766..000000000 --- a/archiva-modules/archiva-maven/archiva-maven-repository/src/test/java/org/apache/archiva/repository/maven/content/MavenRepositoryRequestInfoTest.java +++ /dev/null @@ -1,587 +0,0 @@ -package org.apache.archiva.repository.maven.content; - -/* - * 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.filelock.FileLockManager; -import org.apache.archiva.common.utils.FileUtils; -import org.apache.archiva.configuration.ArchivaConfiguration; -import org.apache.archiva.configuration.FileType; -import org.apache.archiva.configuration.FileTypes; -import org.apache.archiva.metadata.repository.storage.RepositoryPathTranslator; -import org.apache.archiva.repository.ManagedRepositoryContent; -import org.apache.archiva.repository.RepositoryContentProvider; -import org.apache.archiva.repository.content.ItemSelector; -import org.apache.archiva.repository.content.LayoutException; -import org.apache.archiva.repository.maven.MavenManagedRepository; -import org.apache.archiva.repository.maven.metadata.storage.ArtifactMappingProvider; -import org.apache.archiva.test.utils.ArchivaSpringJUnit4ClassRunner; -import org.apache.commons.lang3.StringUtils; -import org.junit.Before; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.springframework.context.ApplicationContext; -import org.springframework.test.context.ContextConfiguration; - -import javax.inject.Inject; -import javax.inject.Named; -import java.io.IOException; -import java.net.URISyntaxException; -import java.nio.file.Path; -import java.nio.file.Paths; -import java.util.List; - -import static org.junit.Assert.*; - -/** - * RepositoryRequestTest - */ -@RunWith( ArchivaSpringJUnit4ClassRunner.class ) -@ContextConfiguration( { "classpath*:/META-INF/spring-context.xml", - "classpath:/spring-context-repo-request-test.xml" } ) -public class MavenRepositoryRequestInfoTest -{ - - @Inject - protected ApplicationContext applicationContext; - - @Inject - FileTypes fileTypes; - - @Inject - @Named( "archivaConfiguration#repo-request-test" ) - private ArchivaConfiguration archivaConfiguration; - - @Inject - List artifactMappingProviders; - - @Inject - @Named( "repositoryPathTranslator#maven2" ) - RepositoryPathTranslator pathTranslator; - - @Inject - FileLockManager fileLockManager; - - @Inject - MavenContentHelper mavenContentHelper; - - private MavenRepositoryRequestInfo repoRequest; - - - protected MavenManagedRepository createRepository( String id, String name, Path location ) throws IOException { - MavenManagedRepository repo = MavenManagedRepository.newLocalInstance( id, name, location.getParent().toAbsolutePath()); - repo.setLocation( location.toAbsolutePath().toUri() ); - return repo; - } - - private Path getRepositoryPath(String repoName) { - try - { - return Paths.get( Thread.currentThread( ).getContextClassLoader( ).getResource( "repositories/" + repoName ).toURI( ) ); - } - catch ( URISyntaxException e ) - { - throw new RuntimeException( "Could not resolve repository path " + e.getMessage( ), e ); - } - } - - @Before - public void setUp() - throws Exception - { - - Path repoDir = getRepositoryPath( "default-repository" ); - MavenManagedRepository repository = createRepository( "testRepo", "Unit Test Repo", repoDir ); - - FileType fileType = archivaConfiguration.getConfiguration().getRepositoryScanning().getFileTypes().get( 0 ); - fileType.addPattern( "**/*.xml" ); - assertEquals( FileTypes.ARTIFACTS, fileType.getId() ); - - fileTypes.afterConfigurationChange( null, "fileType", null ); - - ManagedDefaultRepositoryContent repoContent = new ManagedDefaultRepositoryContent(repository, fileTypes, fileLockManager); - //repoContent = (ManagedRepositoryContent) lookup( ManagedRepositoryContent.class, "default" ); - repository.setContent(repoContent); - repoContent.setMavenContentHelper( mavenContentHelper ); - repoContent.setArtifactMappingProviders( artifactMappingProviders ); - repoContent.setPathTranslator( pathTranslator ); - - repoRequest = new MavenRepositoryRequestInfo(repository); - } - - @Test - public void testInvalidRequestEmptyPath() - { - assertInvalidRequest( "" ); - } - - @Test - public void testInvalidRequestSlashOnly() - { - assertInvalidRequest( "//" ); - } - - @Test - public void testInvalidRequestNoArtifactId() - { - assertInvalidRequest( "groupId/jars/-1.0.jar" ); - } - - - @Test - public void testInvalidRequestTooShort() - { - assertInvalidRequest( "org.apache.maven.test/artifactId-2.0.jar" ); - } - - @Test - public void testInvalidDefaultRequestBadLocation() - { - assertInvalidRequest( "invalid/invalid/1.0-20050611.123456-1/invalid-1.0-20050611.123456-1.jar" ); - } - - @Test( expected = LayoutException.class ) - public void testValidLegacyGanymed() - throws Exception - { - assertValid( "ch.ethz.ganymed/jars/ganymed-ssh2-build210.jar", "ch.ethz.ganymed", "ganymed-ssh2", "build210", - "build210", null, "jar" ); - } - - @Test - public void testValidDefaultGanymed() - throws Exception - { - assertValid( "ch/ethz/ganymed/ganymed-ssh2/build210/ganymed-ssh2-build210.jar", "ch.ethz.ganymed", - "ganymed-ssh2", "build210", "build210", null, "jar" ); - } - - @Test( expected = LayoutException.class ) - public void testValidLegacyJavaxComm() - throws Exception - { - assertValid( "javax/jars/comm-3.0-u1.jar", "javax", "comm", "3.0-u1", "3.0-u1", null, "jar" ); - } - - @Test - public void testValidDefaultJavaxComm() - throws Exception - { - assertValid( "javax/comm/3.0-u1/comm-3.0-u1.jar", "javax", "comm", "3.0-u1", "3.0-u1", null, "jar" ); - } - - @Test( expected = LayoutException.class ) - public void testValidLegacyJavaxPersistence() - throws Exception - { - assertValid( "javax.persistence/jars/ejb-3.0-public_review.jar", "javax.persistence", "ejb", - "3.0-public_review", "3.0-public_review", null, "jar" ); - } - - @Test - public void testValidDefaultJavaxPersistence() - throws Exception - { - assertValid( "javax/persistence/ejb/3.0-public_review/ejb-3.0-public_review.jar", "javax.persistence", "ejb", - "3.0-public_review", "3.0-public_review",null, "jar" ); - } - - @Test( expected = LayoutException.class ) - public void testValidLegacyMavenTestPlugin() - throws Exception - { - assertValid( "maven/jars/maven-test-plugin-1.8.2.jar", "maven", "maven-test-plugin", "1.8.2", "1.8.2",null, "jar" ); - } - - @Test - public void testValidDefaultMavenTestPlugin() - throws Exception - { - assertValid( "maven/maven-test-plugin/1.8.2/maven-test-plugin-1.8.2.pom", "maven", "maven-test-plugin", "1.8.2", "1.8.2", - null, "pom" ); - } - - @Test( expected = LayoutException.class ) - public void testValidLegacyCommonsLangJavadoc() - throws Exception - { - assertValid( "commons-lang/javadoc.jars/commons-lang-2.1-javadoc.jar", "commons-lang", "commons-lang", "2.1", "2.1", - "javadoc", "javadoc" ); - } - - @Test - public void testValidDefaultCommonsLangJavadoc() - throws Exception - { - assertValid( "commons-lang/commons-lang/2.1/commons-lang-2.1-javadoc.jar", "commons-lang", "commons-lang", - "2.1", "2.1","javadoc", "javadoc" ); - } - - @Test( expected = LayoutException.class ) - public void testValidLegacyDerbyPom() - throws Exception - { - assertValid( "org.apache.derby/poms/derby-10.2.2.0.pom", "org.apache.derby", "derby", "10.2.2.0", "10.2.2.0",null, "pom" ); - // Starting slash should not prevent detection. - assertValid( "/org.apache.derby/poms/derby-10.2.2.0.pom", "org.apache.derby", "derby", "10.2.2.0", "10.2.2.0",null, - "pom" ); - } - - @Test - public void testValidDefaultDerbyPom() - throws Exception - { - assertValid( "org/apache/derby/derby/10.2.2.0/derby-10.2.2.0.pom", "org.apache.derby", "derby", "10.2.2.0", "10.2.2.0", - null, "pom" ); - } - - @Test( expected = LayoutException.class ) - public void testValidLegacyGeronimoEjbSpec() - throws Exception - { - assertValid( "org.apache.geronimo.specs/jars/geronimo-ejb_2.1_spec-1.0.1.jar", "org.apache.geronimo.specs", - "geronimo-ejb_2.1_spec", "1.0.1", "1.0.1",null, "jar" ); - } - - @Test - public void testValidDefaultGeronimoEjbSpec() - throws Exception - { - assertValid( "org/apache/geronimo/specs/geronimo-ejb_2.1_spec/1.0.1/geronimo-ejb_2.1_spec-1.0.1.jar", - "org.apache.geronimo.specs", "geronimo-ejb_2.1_spec", "1.0.1", "1.0.1",null, "jar" ); - } - - @Test( expected = LayoutException.class ) - public void testValidLegacyLdapSnapshot() - throws Exception - { - assertValid( "directory-clients/poms/ldap-clients-0.9.1-SNAPSHOT.pom", "directory-clients", "ldap-clients", - "0.9.1-SNAPSHOT", "0.9.1-SNAPSHOT",null, "pom" ); - } - - @Test - public void testValidDefaultLdapSnapshot() - throws Exception - { - assertValid( "directory-clients/ldap-clients/0.9.1-SNAPSHOT/ldap-clients-0.9.1-SNAPSHOT.pom", - "directory-clients", "ldap-clients", "0.9.1-SNAPSHOT", "0.9.1-SNAPSHOT",null, "pom" ); - } - - @Test( expected = LayoutException.class ) - public void testValidLegacyTestArchSnapshot() - throws Exception - { - assertValid( "test.maven-arch/poms/test-arch-2.0.3-SNAPSHOT.pom", "test.maven-arch", "test-arch", - "2.0.3-SNAPSHOT", "2.0.3-SNAPSHOT",null, "pom" ); - } - - @Test - public void testValidDefaultTestArchSnapshot() - throws Exception - { - assertValid( "test/maven-arch/test-arch/2.0.3-SNAPSHOT/test-arch-2.0.3-SNAPSHOT.pom", "test.maven-arch", - "test-arch", "2.0.3-SNAPSHOT", "2.0.3-SNAPSHOT",null, "pom" ); - } - - @Test( expected = LayoutException.class ) - public void testValidLegacyOddDottedArtifactId() - throws Exception - { - assertValid( "com.company.department/poms/com.company.department.project-0.2.pom", "com.company.department", - "com.company.department.project", "0.2", "0.2",null, "pom" ); - } - - @Test - public void testValidDefaultOddDottedArtifactId() - throws Exception - { - assertValid( "com/company/department/com.company.department.project/0.2/com.company.department.project-0.2.pom", - "com.company.department", "com.company.department.project", "0.2", "0.2",null, "pom" ); - } - - @Test( expected = LayoutException.class ) - public void testValidLegacyTimestampedSnapshot() - throws Exception - { - assertValid( "org.apache.archiva.test/jars/redonkulous-3.1-beta-1-20050831.101112-42.jar", - "org.apache.archiva.test", "redonkulous", "3.1-beta-1-20050831.101112-42", "3.1-beta-1-20050831.101112-42", null, "jar" ); - } - - @Test - public void testValidDefaultTimestampedSnapshot() - throws Exception - { - assertValid( - "org/apache/archiva/test/redonkulous/3.1-beta-1-SNAPSHOT/redonkulous-3.1-beta-1-20050831.101112-42.jar", - "org.apache.archiva.test", "redonkulous", "3.1-beta-1-SNAPSHOT", "3.1-beta-1-20050831.101112-42", null, "jar" ); - } - - @Test - public void testIsSupportFile() - { - assertTrue( repoRequest.isSupportFile( "org/apache/derby/derby/10.2.2.0/derby-10.2.2.0-bin.tar.gz.sha1" ) ); - assertTrue( repoRequest.isSupportFile( "org/apache/derby/derby/10.2.2.0/derby-10.2.2.0-bin.tar.gz.md5" ) ); - assertTrue( repoRequest.isSupportFile( "org/apache/derby/derby/10.2.2.0/derby-10.2.2.0-bin.tar.gz.asc" ) ); - assertTrue( repoRequest.isSupportFile( "org/apache/derby/derby/10.2.2.0/derby-10.2.2.0-bin.tar.gz.pgp" ) ); - assertTrue( repoRequest.isSupportFile( "org/apache/derby/derby/10.2.2.0/maven-metadata.xml.sha1" ) ); - assertTrue( repoRequest.isSupportFile( "org/apache/derby/derby/10.2.2.0/maven-metadata.xml.md5" ) ); - - assertFalse( repoRequest.isSupportFile( "test.maven-arch/poms/test-arch-2.0.3-SNAPSHOT.pom" ) ); - assertFalse( - repoRequest.isSupportFile( "test/maven-arch/test-arch/2.0.3-SNAPSHOT/test-arch-2.0.3-SNAPSHOT.jar" ) ); - assertFalse( repoRequest.isSupportFile( "org/apache/archiva/archiva-api/1.0/archiva-api-1.0.xml.zip" ) ); - assertFalse( repoRequest.isSupportFile( "org/apache/derby/derby/10.2.2.0/derby-10.2.2.0-bin.tar.gz" ) ); - assertFalse( repoRequest.isSupportFile( "org/apache/derby/derby/10.2.2.0/maven-metadata.xml" ) ); - assertFalse( repoRequest.isSupportFile( "org/apache/derby/derby/maven-metadata.xml" ) ); - } - - @Test - public void testIsMetadata() - { - assertTrue( repoRequest.isMetadata( "org/apache/derby/derby/10.2.2.0/maven-metadata.xml" ) ); - assertTrue( repoRequest.isMetadata( "org/apache/derby/derby/maven-metadata.xml" ) ); - - assertFalse( repoRequest.isMetadata( "test.maven-arch/poms/test-arch-2.0.3-SNAPSHOT.pom" ) ); - assertFalse( - repoRequest.isMetadata( "test/maven-arch/test-arch/2.0.3-SNAPSHOT/test-arch-2.0.3-SNAPSHOT.jar" ) ); - assertFalse( repoRequest.isMetadata( "org/apache/archiva/archiva-api/1.0/archiva-api-1.0.xml.zip" ) ); - assertFalse( repoRequest.isMetadata( "org/apache/derby/derby/10.2.2.0/derby-10.2.2.0-bin.tar.gz" ) ); - assertFalse( repoRequest.isMetadata( "org/apache/derby/derby/10.2.2.0/derby-10.2.2.0-bin.tar.gz.pgp" ) ); - assertFalse( repoRequest.isMetadata( "org/apache/derby/derby/10.2.2.0/maven-metadata.xml.sha1" ) ); - } - - @Test - public void testIsMetadataSupportFile() - { - assertFalse( repoRequest.isMetadataSupportFile( "org/apache/derby/derby/10.2.2.0/maven-metadata.xml" ) ); - assertFalse( repoRequest.isMetadataSupportFile( "org/apache/derby/derby/maven-metadata.xml" ) ); - assertTrue( repoRequest.isMetadataSupportFile( "org/apache/derby/derby/maven-metadata.xml.sha1" ) ); - assertTrue( repoRequest.isMetadataSupportFile( "org/apache/derby/derby/maven-metadata.xml.md5" ) ); - - assertFalse( repoRequest.isMetadataSupportFile( "test.maven-arch/poms/test-arch-2.0.3-SNAPSHOT.pom" ) ); - assertFalse( repoRequest.isMetadataSupportFile( - "test/maven-arch/test-arch/2.0.3-SNAPSHOT/test-arch-2.0.3-SNAPSHOT.jar" ) ); - assertFalse( - repoRequest.isMetadataSupportFile( "org/apache/archiva/archiva-api/1.0/archiva-api-1.0.xml.zip" ) ); - assertFalse( repoRequest.isMetadataSupportFile( "org/apache/derby/derby/10.2.2.0/derby-10.2.2.0-bin.tar.gz" ) ); - assertFalse( - repoRequest.isMetadataSupportFile( "org/apache/derby/derby/10.2.2.0/derby-10.2.2.0-bin.tar.gz.pgp" ) ); - assertTrue( repoRequest.isMetadataSupportFile( "org/apache/derby/derby/10.2.2.0/maven-metadata.xml.sha1" ) ); - assertTrue( repoRequest.isMetadataSupportFile( "org/apache/derby/derby/10.2.2.0/maven-metadata.xml.md5" ) ); - } - - @Test - public void testIsDefault() - { - assertNotEquals( "default", repoRequest.getLayout( "test.maven-arch/poms/test-arch-2.0.3-SNAPSHOT.pom" ) ); - assertNotEquals("default", repoRequest.getLayout( "directory-clients/poms/ldap-clients-0.9.1-SNAPSHOT.pom" ) ); - assertNotEquals("default", repoRequest.getLayout( "commons-lang/jars/commons-lang-2.1-javadoc.jar" ) ); - - assertEquals("default", repoRequest.getLayout( "test/maven-arch/test-arch/2.0.3-SNAPSHOT/test-arch-2.0.3-SNAPSHOT.jar" ) ); - assertEquals("default", repoRequest.getLayout( "org/apache/archiva/archiva-api/1.0/archiva-api-1.0.xml.zip" ) ); - assertEquals("default", repoRequest.getLayout( "org/apache/derby/derby/10.2.2.0/derby-10.2.2.0-bin.tar.gz" ) ); - assertEquals("default", repoRequest.getLayout( "org/apache/derby/derby/10.2.2.0/derby-10.2.2.0-bin.tar.gz.pgp" ) ); - assertEquals("default", repoRequest.getLayout( "org/apache/derby/derby/10.2.2.0/maven-metadata.xml.sha1" ) ); - assertEquals("default", repoRequest.getLayout( "eclipse/jdtcore/maven-metadata.xml" ) ); - assertEquals("default", repoRequest.getLayout( "eclipse/jdtcore/maven-metadata.xml.sha1" ) ); - assertEquals("default", repoRequest.getLayout( "eclipse/jdtcore/maven-metadata.xml.md5" ) ); - - assertNotEquals("default", repoRequest.getLayout( null ) ); - assertNotEquals("default", repoRequest.getLayout( "" ) ); - assertNotEquals("default", repoRequest.getLayout( "foo" ) ); - assertNotEquals("default", repoRequest.getLayout( "some.short/path" ) ); - } - - @Test - public void testIsLegacy() - { - assertEquals("legacy", repoRequest.getLayout( "test.maven-arch/poms/test-arch-2.0.3-SNAPSHOT.pom" ) ); - assertEquals("legacy", repoRequest.getLayout( "directory-clients/poms/ldap-clients-0.9.1-SNAPSHOT.pom" ) ); - assertEquals("legacy", repoRequest.getLayout( "commons-lang/jars/commons-lang-2.1-javadoc.jar" ) ); - - assertNotEquals("legacy", repoRequest.getLayout( "test/maven-arch/test-arch/2.0.3-SNAPSHOT/test-arch-2.0.3-SNAPSHOT.jar" ) ); - assertNotEquals("legacy", repoRequest.getLayout( "org/apache/archiva/archiva-api/1.0/archiva-api-1.0.xml.zip" ) ); - assertNotEquals("legacy", repoRequest.getLayout( "org/apache/derby/derby/10.2.2.0/derby-10.2.2.0-bin.tar.gz" ) ); - assertNotEquals("legacy", repoRequest.getLayout( "org/apache/derby/derby/10.2.2.0/derby-10.2.2.0-bin.tar.gz.pgp" ) ); - assertNotEquals("legacy", repoRequest.getLayout( "org/apache/derby/derby/10.2.2.0/maven-metadata.xml.sha1" ) ); - - assertNotEquals("legacy", repoRequest.getLayout( null ) ); - assertNotEquals("legacy", repoRequest.getLayout( "" ) ); - assertNotEquals("legacy", repoRequest.getLayout( "some.short/path" ) ); - } - - private ManagedRepositoryContent createManagedRepo( String layout ) - throws Exception - { - Path repoRoot = Paths.get( FileUtils.getBasedir() + "/target/test-repo" ); - return createManagedRepositoryContent( "test-internal", "Internal Test Repo", repoRoot, layout ); - } - - /** - * [MRM-481] Artifact requests with a .xml.zip extension fail with a 404 Error - */ - @Test - public void testToNativePathArtifactDefaultToDefaultDualExtension() - throws Exception - { - ManagedRepositoryContent repository = createManagedRepo( "default" ); - - // Test (artifact) default to default - dual extension - assertEquals( "/org/project/example-presentation/3.2/example-presentation-3.2.xml.zip", - repoRequest.toNativePath( "org/project/example-presentation/3.2/example-presentation-3.2.xml.zip") ); - } - - - @Test - public void testToNativePathMetadataDefaultToDefault() - throws Exception - { - ManagedRepositoryContent repository = createManagedRepo( "default" ); - - // Test (metadata) default to default - assertEquals( "/org/apache/derby/derby/10.2.2.0/maven-metadata.xml.sha1", - repoRequest.toNativePath( "org/apache/derby/derby/10.2.2.0/maven-metadata.xml.sha1") ); - } - - - @Test - public void testNativePathBadRequestTooShort() - throws Exception - { - ManagedRepositoryContent repository = createManagedRepo( "default" ); - - // Test bad request path (too short) - try - { - repoRequest.toNativePath( "org.apache.derby/license.txt"); - fail( "Should have thrown an exception about a too short path." ); - } - catch ( LayoutException e ) - { - // expected path. - } - } - - @Test - public void testNativePathBadRequestBlank() - throws Exception - { - ManagedRepositoryContent repository = createManagedRepo( "default" ); - - // Test bad request path (too short) - try - { - repoRequest.toNativePath( ""); - fail( "Should have thrown an exception about an blank request." ); - } - catch ( LayoutException e ) - { - // expected path. - } - } - - @Test - public void testNativePathBadRequestNull() - throws Exception - { - ManagedRepositoryContent repository = createManagedRepo( "default" ); - - // Test bad request path (too short) - try - { - repoRequest.toNativePath( null); - fail( "Should have thrown an exception about an null request." ); - } - catch ( LayoutException e ) - { - // expected path. - } - } - - @Test - public void testNativePathBadRequestUnknownType() - throws Exception - { - ManagedRepositoryContent repository = createManagedRepo( "default" ); - - // Test bad request path (too short) - try - { - repoRequest.toNativePath( "org/apache/derby/derby/10.2.2.0/license.txt"); - fail( "Should have thrown an exception about an invalid type." ); - } - catch ( LayoutException e ) - { - // expected path. - } - } - - - private void assertValid( String path, String groupId, String artifactId, String version, String artifactVersion, String classifier, - String type ) - throws Exception - { - String expectedId = - "ArtifactReference - " + groupId + ":" + artifactId + ":" + version + ":" + ( classifier != null ? - classifier + ":" : "" ) + type; - - ItemSelector reference = repoRequest.toItemSelector( path ); - - assertNotNull( expectedId + " - Should not be null.", reference ); - - assertEquals( expectedId + " - Group ID", groupId, reference.getNamespace() ); - assertEquals( expectedId + " - Artifact ID", artifactId, reference.getArtifactId() ); - assertEquals( expectedId + " - Artifact Version", artifactVersion, reference.getArtifactVersion( ) ); - if ( StringUtils.isNotBlank( classifier ) ) - { - assertEquals( expectedId + " - Classifier", classifier, reference.getClassifier() ); - } - assertEquals( expectedId + " - Version ID", version, reference.getVersion() ); - assertEquals( expectedId + " - Type", type, reference.getType() ); - } - - private void assertInvalidRequest( String path ) - { - try - { - repoRequest.toItemSelector( path ); - fail( "Expected a LayoutException on an invalid path [" + path + "]" ); - } - catch ( LayoutException e ) - { - /* expected path */ - } - } - - protected ManagedRepositoryContent createManagedRepositoryContent( String id, String name, Path location, - String layout ) - throws Exception - { - MavenManagedRepository repo = MavenManagedRepository.newLocalInstance( id, name, archivaConfiguration.getRepositoryBaseDir()); - repo.setLocation( location.toAbsolutePath().toUri() ); - repo.setLayout( layout ); - - RepositoryContentProvider provider = applicationContext.getBean( "repositoryContentProvider#maven", RepositoryContentProvider.class ); - - ManagedRepositoryContent repoContent = - provider.createManagedContent( repo ); - - return repoContent; - } - -} diff --git a/archiva-modules/archiva-maven/archiva-maven-repository/src/test/java/org/apache/archiva/repository/maven/content/RemoteDefaultRepositoryContentTest.java b/archiva-modules/archiva-maven/archiva-maven-repository/src/test/java/org/apache/archiva/repository/maven/content/RemoteDefaultRepositoryContentTest.java deleted file mode 100644 index 65c242a25..000000000 --- a/archiva-modules/archiva-maven/archiva-maven-repository/src/test/java/org/apache/archiva/repository/maven/content/RemoteDefaultRepositoryContentTest.java +++ /dev/null @@ -1,102 +0,0 @@ -package org.apache.archiva.repository.maven.content; - -/* - * 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.metadata.repository.storage.RepositoryPathTranslator; -import org.apache.archiva.repository.ManagedRepositoryContent; -import org.apache.archiva.repository.RemoteRepository; -import org.apache.archiva.repository.RepositoryContent; -import org.apache.archiva.repository.content.Artifact; -import org.apache.archiva.repository.content.ItemSelector; -import org.apache.archiva.repository.content.LayoutException; -import org.apache.archiva.repository.maven.metadata.storage.ArtifactMappingProvider; -import org.junit.Before; - -import javax.inject.Inject; -import javax.inject.Named; -import java.util.List; - -/** - * RemoteDefaultRepositoryContentTest - */ -public class RemoteDefaultRepositoryContentTest - extends AbstractRepositoryContentTest -{ - - @Inject - private List artifactMappingProviders; - - @Inject - @Named( "repositoryPathTranslator#maven2" ) - RepositoryPathTranslator pathTranslator; - - private RemoteDefaultRepositoryContent repoContent; - - @Before - public void setUp() - throws Exception - { - RemoteRepository repository = - createRemoteRepository( "testRemoteRepo", "Unit Test Remote Repo", "http://repo1.maven.org/maven2/" ); - - repoContent = new RemoteDefaultRepositoryContent(); - repoContent.setArtifactMappingProviders( artifactMappingProviders ); - repoContent.setPathTranslator( pathTranslator ); - - //repoContent = (RemoteRepositoryContent) lookup( RemoteRepositoryContent.class, "default" ); - repoContent.setRepository( repository ); - } - - @Override - protected Artifact createArtifact( String groupId, String artifactId, String version, String classifier, String type ) throws LayoutException - { - return null; - } - - - @Override - protected String toPath( Artifact reference ) throws LayoutException - { - ItemSelector selector = toItemSelector( reference.getAsset( ).getPath( ) ); - return repoContent.toPath( selector ); - } - - @Override - protected ItemSelector toItemSelector( String path ) throws LayoutException - { - return repoContent.toItemSelector( path ); - } - - @Override - protected ManagedRepositoryContent getManaged( ) - { - return null; - } - - @Override - protected RepositoryContent getContent( ) - { - return repoContent; - } - - @Override - protected String toPath( ItemSelector selector ) { - return repoContent.toPath( selector ); - } -} diff --git a/archiva-modules/archiva-maven/archiva-maven-repository/src/test/java/org/apache/archiva/repository/maven/dependency/tree/DependencyTreeBuilderTestMaven3.java b/archiva-modules/archiva-maven/archiva-maven-repository/src/test/java/org/apache/archiva/repository/maven/dependency/tree/DependencyTreeBuilderTestMaven3.java deleted file mode 100644 index 5323deb6a..000000000 --- a/archiva-modules/archiva-maven/archiva-maven-repository/src/test/java/org/apache/archiva/repository/maven/dependency/tree/DependencyTreeBuilderTestMaven3.java +++ /dev/null @@ -1,143 +0,0 @@ -package org.apache.archiva.repository.maven.dependency.tree; - -/* - * 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.configuration.ArchivaConfiguration; -import org.apache.archiva.configuration.Configuration; -import org.apache.archiva.configuration.ManagedRepositoryConfiguration; -import org.apache.archiva.maven.model.Artifact; -import org.apache.archiva.maven.model.TreeEntry; -import org.apache.archiva.repository.RepositoryRegistry; -import org.apache.archiva.test.utils.ArchivaSpringJUnit4ClassRunner; -import org.junit.Before; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.springframework.test.context.ContextConfiguration; - -import javax.inject.Inject; -import javax.inject.Named; -import java.nio.file.Paths; -import java.util.Collections; -import java.util.List; - -import static org.assertj.core.api.Assertions.assertThat; - -@RunWith( ArchivaSpringJUnit4ClassRunner.class ) -@ContextConfiguration( { "classpath*:/META-INF/spring-context.xml", "classpath:/spring-context.xml" } ) -public class DependencyTreeBuilderTestMaven3 - extends TestCase -{ - @Inject - @Named( "dependencyTreeBuilder#maven3" ) - private Maven3DependencyTreeBuilder builder; - - private static final String TEST_REPO_ID = "test"; - - private static final String TEST_VERSION = "1.2.1"; - - private static final String TEST_ARTIFACT_ID = "archiva-common"; - - private static final String TEST_GROUP_ID = "org.apache.archiva"; - - - @Inject - @Named( "archivaConfiguration#test" ) - ArchivaConfiguration config; - - @Inject - RepositoryRegistry repositoryRegistry; - - @Before - @Override - public void setUp() - throws Exception - { - super.setUp(); - - Configuration configuration = new Configuration(); - ManagedRepositoryConfiguration repoConfig = new ManagedRepositoryConfiguration(); - repoConfig.setId( TEST_REPO_ID ); - repoConfig.setLocation(Paths.get("target/test-repository").toAbsolutePath().toString() ); - configuration.addManagedRepository( repoConfig ); - - config.getConfiguration().getProxyConnectors().clear(); - config.save( configuration ); - - repositoryRegistry.reload(); - - //artifactFactory = ((DefaultDependencyTreeBuilder)this.builder).getFactory(); - } - - - private Artifact createArtifact( String groupId, String artifactId, String version ) - { - return new Artifact( groupId, artifactId, version ); - } - - private String getId( Artifact artifact ) - { - return artifact.getGroupId() + ":" + artifact.getArtifactId() + ":" + artifact.getVersion(); - } - - @Test - public void testBuilderDependencies() - throws Exception - { - - List treeEntries = - builder.buildDependencyTree( Collections.singletonList( TEST_REPO_ID ), TEST_GROUP_ID, TEST_ARTIFACT_ID, - TEST_VERSION ); - - Artifact artifact = new Artifact( TEST_GROUP_ID, TEST_ARTIFACT_ID, TEST_VERSION, "", "" ); - artifact.setFileExtension("jar"); - assertThat( treeEntries ).isNotNull().isNotEmpty().contains(new TreeEntry(artifact) ); - - artifact = new Artifact( "commons-lang", "commons-lang", "2.2", "compile", "" ); - artifact.setFileExtension("jar"); - assertThat( treeEntries.get( 0 ).getChilds() ).isNotNull().isNotEmpty().contains( - new TreeEntry(artifact) ); - } - - - public static class TestTreeEntry - extends TreeEntry - { - Artifact a; - - public TestTreeEntry( Artifact a ) - { - this.a = a; - } - - @Override - public int hashCode() - { - return this.a.hashCode(); - } - - @Override - public boolean equals( Object o ) - { - Artifact artifact = ( (TreeEntry) o ).getArtifact(); - return artifact.equals( this.a ); - } - } - -} diff --git a/archiva-modules/archiva-maven/archiva-maven-repository/src/test/java/org/apache/archiva/repository/maven/merge/Maven2RepositoryMergerTest.java b/archiva-modules/archiva-maven/archiva-maven-repository/src/test/java/org/apache/archiva/repository/maven/merge/Maven2RepositoryMergerTest.java deleted file mode 100644 index fe1779032..000000000 --- a/archiva-modules/archiva-maven/archiva-maven-repository/src/test/java/org/apache/archiva/repository/maven/merge/Maven2RepositoryMergerTest.java +++ /dev/null @@ -1,213 +0,0 @@ -package org.apache.archiva.repository.maven.merge; - -/* - * 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.configuration.ArchivaConfiguration; -import org.apache.archiva.configuration.Configuration; -import org.apache.archiva.configuration.ManagedRepositoryConfiguration; -import org.apache.archiva.configuration.RepositoryScanningConfiguration; -import org.apache.archiva.metadata.model.ArtifactMetadata; -import org.apache.archiva.metadata.repository.MetadataRepository; -import org.apache.archiva.metadata.repository.MetadataRepositoryException; -import org.apache.archiva.metadata.repository.RepositorySession; -import org.apache.archiva.metadata.repository.RepositorySessionFactory; -import org.apache.archiva.test.utils.ArchivaSpringJUnit4ClassRunner; -import org.junit.Before; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.mockito.MockitoAnnotations; -import org.springframework.test.context.ContextConfiguration; - -import javax.inject.Inject; -import javax.inject.Named; -import java.nio.file.Files; -import java.nio.file.Path; -import java.nio.file.Paths; -import java.util.ArrayList; -import java.util.List; - -import static org.mockito.Mockito.*; - -@RunWith (ArchivaSpringJUnit4ClassRunner.class) -@ContextConfiguration (locations = { "classpath*:/META-INF/spring-context.xml", "classpath*:/spring-context-merge.xml" }) -public class Maven2RepositoryMergerTest - extends TestCase -{ - - private static final String TEST_REPO_ID = "test"; - - @Inject - private Maven2RepositoryMerger repositoryMerger; - - @Inject - @Named("archivaConfiguration#default") - ArchivaConfiguration configuration; - - private MetadataRepository metadataRepository; - - private static RepositorySessionFactory repositorySessionFactory; - - private static RepositorySession session; - - static - { - repositorySessionFactory = mock(RepositorySessionFactory.class); - session = mock( RepositorySession.class ); - - try - { - when( repositorySessionFactory.createSession( ) ).thenReturn( session ); - } - catch ( MetadataRepositoryException e ) - { - throw new RuntimeException( e ); - } - - } - - public static RepositorySessionFactory getRepositorySessionFactory() { - return repositorySessionFactory; - } - - - - @Before - @Override - public void setUp() - throws Exception - { - super.setUp(); - MockitoAnnotations.initMocks( this ); - metadataRepository = mock( MetadataRepository.class ); - repositoryMerger.setRepositorySessionFactory( repositorySessionFactory ); - - } - - private List getArtifacts() - { - List metadata = new ArrayList<>(); - ArtifactMetadata artifact1 = new ArtifactMetadata(); - artifact1.setNamespace( "com.example.test" ); - artifact1.setProject( "test-artifact" ); - artifact1.setVersion( "1.0-SNAPSHOT" ); - artifact1.setProjectVersion( "1.0-SNAPSHOT" ); - artifact1.setId( "test-artifact-1.0-20100308.230825-1.jar" ); - - metadata.add( artifact1 ); - return metadata; - } - - @Test - public void testMerge() - throws Exception - { - String targetRepoPath = "target/test-repository-target"; - Path mergedArtifact = Paths.get( targetRepoPath, - "com/example/test/test-artifact/1.0-SNAPSHOT/test-artifact-1.0-20100308.230825-1.jar" ); - - Path mavenMetadata = Paths.get( targetRepoPath, "com/example/test/test-artifact/maven-metadata.xml" ); - - Path pom = Paths.get( targetRepoPath, - "com/example/test/test-artifact/1.0-SNAPSHOT/test-artifact-1.0-20100308.230825-1.pom" ); - - for (Path testArtifact : new Path[] { mergedArtifact, mavenMetadata, pom }) { - Files.deleteIfExists(testArtifact); - } - - assertFalse( "Artifact file exists already", Files.exists(mergedArtifact) ); - assertFalse( "Metadata file exists already", Files.exists(mavenMetadata) ); - assertFalse( "Pom File exists already", Files.exists(pom) ); - Configuration c = new Configuration(); - ManagedRepositoryConfiguration testRepo = new ManagedRepositoryConfiguration(); - testRepo.setId( TEST_REPO_ID ); - testRepo.setLocation( "target/test-repository" ); - - RepositoryScanningConfiguration repoScanConfig = new RepositoryScanningConfiguration(); - List knownContentConsumers = new ArrayList<>(); - knownContentConsumers.add( "metadata-updater12" ); - repoScanConfig.setKnownContentConsumers( knownContentConsumers ); - c.setRepositoryScanning( repoScanConfig ); - - ManagedRepositoryConfiguration targetRepo = new ManagedRepositoryConfiguration(); - targetRepo.setId( "target-rep" ); - targetRepo.setLocation( targetRepoPath ); - c.addManagedRepository( testRepo ); - c.addManagedRepository( targetRepo ); - configuration.save( c ); - - - when(metadataRepository.getArtifacts(session, TEST_REPO_ID)).thenReturn(getArtifacts()); - repositoryMerger.merge(metadataRepository, TEST_REPO_ID, "target-rep"); - verify(metadataRepository).getArtifacts(session, TEST_REPO_ID); - assertTrue( Files.exists(mergedArtifact) ); - assertTrue( Files.exists(mavenMetadata) ); - assertTrue( Files.exists(pom) ); - } - - @Test - public void testMergeWithOutConflictArtifacts() - throws Exception - { - String sourceRepoId = "source-repo"; - ArtifactMetadata artifact1 = new ArtifactMetadata(); - artifact1.setNamespace( "org.testng" ); - artifact1.setProject( "testng" ); - artifact1.setVersion( "5.8" ); - artifact1.setProjectVersion( "5.8" ); - artifact1.setId( "testng-5.8-jdk15.jar" ); - artifact1.setRepositoryId( sourceRepoId ); - - List sourceRepoArtifactsList = getArtifacts(); - sourceRepoArtifactsList.add( artifact1 ); - List targetRepoArtifactsList = getArtifacts(); - - Configuration c = new Configuration(); - ManagedRepositoryConfiguration testRepo = new ManagedRepositoryConfiguration(); - testRepo.setId( TEST_REPO_ID ); - testRepo.setLocation( "target/test-repository" ); - - String sourceRepo = "src/test/resources/test-repository-with-conflict-artifacts"; - ManagedRepositoryConfiguration testRepoWithConflicts = new ManagedRepositoryConfiguration(); - testRepoWithConflicts.setId( sourceRepoId ); - testRepoWithConflicts.setLocation( sourceRepo ); - - RepositoryScanningConfiguration repoScanConfig = new RepositoryScanningConfiguration(); - List knownContentConsumers = new ArrayList<>(); - knownContentConsumers.add( "metadata-updater" ); - repoScanConfig.setKnownContentConsumers( knownContentConsumers ); - c.setRepositoryScanning( repoScanConfig ); - - c.addManagedRepository( testRepo ); - c.addManagedRepository( testRepoWithConflicts ); - configuration.save( c ); - - Path targetRepoFile = Paths.get( - "/target/test-repository/com/example/test/test-artifact/1.0-SNAPSHOT/test-artifact-1.0-20100308.230825-1.jar" ); - targetRepoFile.toFile().setReadOnly(); - - when(metadataRepository.getArtifacts(session, sourceRepoId)).thenReturn(sourceRepoArtifactsList); - when(metadataRepository.getArtifacts(session, TEST_REPO_ID)).thenReturn(targetRepoArtifactsList); - - assertEquals(1, repositoryMerger.getConflictingArtifacts(metadataRepository, sourceRepoId, - TEST_REPO_ID).size()); - verify(metadataRepository).getArtifacts(session, TEST_REPO_ID); - } - -} \ No newline at end of file diff --git a/archiva-modules/archiva-maven/archiva-maven-repository/src/test/java/org/apache/archiva/repository/maven/metadata/Maven2RepositoryStorageTest.java b/archiva-modules/archiva-maven/archiva-maven-repository/src/test/java/org/apache/archiva/repository/maven/metadata/Maven2RepositoryStorageTest.java deleted file mode 100644 index 0d993358d..000000000 --- a/archiva-modules/archiva-maven/archiva-maven-repository/src/test/java/org/apache/archiva/repository/maven/metadata/Maven2RepositoryStorageTest.java +++ /dev/null @@ -1,64 +0,0 @@ -package org.apache.archiva.repository.maven.metadata; - -/* - * 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.metadata.repository.storage.RepositoryStorage; -import org.apache.archiva.repository.maven.MavenManagedRepository; -import org.apache.archiva.test.utils.ArchivaSpringJUnit4ClassRunner; -import org.junit.Assert; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.springframework.test.context.ContextConfiguration; - -import javax.inject.Inject; -import javax.inject.Named; -import java.io.IOException; -import java.nio.file.Paths; - -/** - * @author Olivier Lamy - */ -@RunWith( ArchivaSpringJUnit4ClassRunner.class ) -@ContextConfiguration( { "classpath*:/spring-context-storage.xml", "classpath*:META-INF/spring-context.xml" } ) -public class Maven2RepositoryStorageTest -{ - @Inject - @Named( "repositoryStorage#maven2" ) - RepositoryStorage repositoryStorage; - - @Test - public void testGetLogicalPath() throws IOException { - String href = "/repository/internal/org/apache/maven/someartifact.jar"; - Assert.assertEquals( "/org/apache/maven/someartifact.jar", - repositoryStorage.getFilePath( href, MavenManagedRepository.newLocalInstance( "repo01", "repo01", Paths.get("target/repositories")) ) ); - - href = "repository/internal/org/apache/maven/someartifact.jar"; - Assert.assertEquals( "/org/apache/maven/someartifact.jar", - repositoryStorage.getFilePath( href, MavenManagedRepository.newLocalInstance( "repo01", "repo01", Paths.get("target/repositories") ) ) ); - - href = "repository/internal/org/apache/maven/"; - Assert.assertEquals( "/org/apache/maven/", repositoryStorage.getFilePath( href, MavenManagedRepository.newLocalInstance("repo01", "repo01", Paths.get("target/repositories")) ) ); - - href = "mypath"; - Assert.assertEquals( "/", repositoryStorage.getFilePath( href, MavenManagedRepository.newLocalInstance("repo01", "repo01", Paths.get("target/repositories")) ) ); - } - - -} - diff --git a/archiva-modules/archiva-maven/archiva-maven-repository/src/test/java/org/apache/archiva/repository/maven/metadata/MetadataToolsTest.java b/archiva-modules/archiva-maven/archiva-maven-repository/src/test/java/org/apache/archiva/repository/maven/metadata/MetadataToolsTest.java deleted file mode 100644 index d8542b1b1..000000000 --- a/archiva-modules/archiva-maven/archiva-maven-repository/src/test/java/org/apache/archiva/repository/maven/metadata/MetadataToolsTest.java +++ /dev/null @@ -1,691 +0,0 @@ -package org.apache.archiva.repository.maven.metadata; - -/* - * 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.utils.VersionComparator; -import org.apache.archiva.configuration.ProxyConnectorConfiguration; -import org.apache.archiva.policies.CachedFailuresPolicy; -import org.apache.archiva.policies.ChecksumPolicy; -import org.apache.archiva.policies.ReleasesPolicy; -import org.apache.archiva.policies.SnapshotsPolicy; -import org.apache.archiva.repository.ManagedRepositoryContent; -import org.apache.archiva.repository.RemoteRepositoryContent; -import org.apache.archiva.repository.RepositoryContentProvider; -import org.apache.archiva.repository.content.ItemSelector; -import org.apache.archiva.repository.content.LayoutException; -import org.apache.archiva.repository.content.base.ArchivaItemSelector; -import org.apache.archiva.repository.maven.AbstractRepositoryLayerTestCase; -import org.apache.archiva.repository.maven.MavenManagedRepository; -import org.apache.archiva.repository.maven.metadata.storage.mock.MockConfiguration; -import org.apache.archiva.repository.metadata.RepositoryMetadataException; -import org.apache.archiva.repository.metadata.base.MetadataTools; -import org.apache.commons.io.FileUtils; -import org.apache.commons.lang3.StringUtils; -import org.junit.Test; -import org.springframework.test.context.ContextConfiguration; -import org.xml.sax.SAXException; -import org.xmlunit.builder.DiffBuilder; -import org.xmlunit.diff.Diff; -import org.xmlunit.diff.Difference; - -import javax.inject.Inject; -import javax.inject.Named; -import javax.xml.parsers.ParserConfigurationException; -import java.io.IOException; -import java.net.URISyntaxException; -import java.nio.charset.Charset; -import java.nio.file.Files; -import java.nio.file.Path; -import java.nio.file.Paths; -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; -import java.util.Set; - -import static org.junit.Assert.*; - -/** - * MetadataToolsTest - */ -@SuppressWarnings( "deprecation" ) -@ContextConfiguration ( - { "classpath*:/META-INF/spring-context.xml", "classpath:/spring-context-metadata-tools-test.xml" } ) -public class MetadataToolsTest - extends AbstractRepositoryLayerTestCase -{ - @Inject - @Named ( "metadataTools#test" ) - private MetadataTools tools; - - @Inject - @Named ( "archivaConfiguration#mock" ) - protected MockConfiguration config; - - private Path getRepositoryPath(String repoName) { - try - { - return Paths.get( Thread.currentThread( ).getContextClassLoader( ).getResource( "repositories/" + repoName ).toURI( ) ); - } - catch ( URISyntaxException e ) - { - throw new RuntimeException( "Could not resolve repository path " + e.getMessage( ), e ); - } - } - - @Test - public void testGatherSnapshotVersionsA() - throws Exception - { - removeProxyConnector( "test-repo", "apache-snapshots" ); - removeProxyConnector( "test-repo", "internal-snapshots" ); - removeProxyConnector( "test-repo", "snapshots.codehaus.org" ); - - assertSnapshotVersions( "snap_shots_a", "1.0-alpha-11-SNAPSHOT", - new String[]{ "1.0-alpha-11-SNAPSHOT", "1.0-alpha-11-20070221.194724-2", - "1.0-alpha-11-20070302.212723-3", "1.0-alpha-11-20070303.152828-4", - "1.0-alpha-11-20070305.215149-5", "1.0-alpha-11-20070307.170909-6", - "1.0-alpha-11-20070314.211405-9", "1.0-alpha-11-20070316.175232-11" } ); - } - - @Test - public void testGatherSnapshotVersionsAWithProxies() - throws Exception - { - // These proxied repositories do not need to exist for the purposes of this unit test, - // just the repository ids are important. - createProxyConnector( "test-repo", "apache-snapshots" ); - createProxyConnector( "test-repo", "internal-snapshots" ); - createProxyConnector( "test-repo", "snapshots.codehaus.org" ); - - assertSnapshotVersions( "snap_shots_a", "1.0-alpha-11-SNAPSHOT", - new String[]{ "1.0-alpha-11-SNAPSHOT", "1.0-alpha-11-20070221.194724-2", - "1.0-alpha-11-20070302.212723-3", "1.0-alpha-11-20070303.152828-4", - "1.0-alpha-11-20070305.215149-5", "1.0-alpha-11-20070307.170909-6", - "1.0-alpha-11-20070314.211405-9", "1.0-alpha-11-20070315.033030-10" - /* Arrives in via snapshots.codehaus.org proxy */, - "1.0-alpha-11-20070316.175232-11" } ); - } - - @Test - public void testGetRepositorySpecificName() - throws Exception - { - RemoteRepositoryContent repoJavaNet = - createRemoteRepositoryContent( "maven2-repository.dev.java.net", "Java.net Repository for Maven 2", - "http://download.java.net/maven/2/", "default" ); - RemoteRepositoryContent repoCentral = - createRemoteRepositoryContent( "central", "Central Global Repository", "http://repo1.maven.org/maven2/", - "default" ); - - String convertedName = - tools.getRepositorySpecificName( repoJavaNet, "commons-lang/commons-lang/maven-metadata.xml" ); - assertMetadataPath( "commons-lang/commons-lang/maven-metadata-maven2-repository.dev.java.net.xml", - convertedName ); - - convertedName = tools.getRepositorySpecificName( repoCentral, "commons-lang/commons-lang/maven-metadata.xml" ); - assertMetadataPath( "commons-lang/commons-lang/maven-metadata-central.xml", convertedName ); - } - - // TODO: replace with group tests -// public void testUpdateProjectBadArtifact() -// throws Exception -// { -// try -// { -// assertUpdatedProjectMetadata( "bad_artifact", null ); -// fail( "Should have thrown an IOException on a bad artifact." ); -// } -// catch ( IOException e ) -// { -// // Expected path -// } -// } - - @Test - public void testUpdateProjectNonExistingVersion() - throws Exception - { - ManagedRepositoryContent testRepo = createTestRepoContent(); - ItemSelector reference = ArchivaItemSelector.builder() - .withNamespace( "org.apache.archiva.metadata.tests" ) - .withProjectId( "missing_artifact" ).build(); - - prepProjectTestRepo( testRepo, reference ); - - // check metadata prior to update -- should contain the non-existing artifact version - assertProjectMetadata( testRepo, reference, "missing_artifact", - new String[]{ "1.0-SNAPSHOT", "1.1-SNAPSHOT", "1.2-SNAPSHOT" }, "1.2-SNAPSHOT", null ); - - tools.updateProjectMetadata( testRepo, reference ); - - // metadata should not contain the non-existing artifact version -- 1.1-SNAPSHOT - assertProjectMetadata( testRepo, reference, "missing_artifact", new String[]{ "1.0-SNAPSHOT", "1.2-SNAPSHOT" }, - "1.2-SNAPSHOT", null ); - } - - @Test - public void testUpdateProjectMissingMultipleVersions() - throws Exception - { - assertUpdatedProjectMetadata( "missing_metadata_b", - new String[]{ "1.0", "1.0.1", "2.0", "2.0.1", "2.0-20070821-dev" }, - "2.0-20070821-dev", "2.0-20070821-dev" ); - } - - @Test - public void testUpdateProjectMissingMultipleVersionsWithProxies() - throws Exception - { - // Attach the (bogus) proxies to the managed repo. - // These proxied repositories do not need to exist for the purposes of this unit test, - // just the repository ids are important. - createProxyConnector( "test-repo", "central" ); - createProxyConnector( "test-repo", "java.net" ); - - assertUpdatedProjectMetadata( "proxied_multi", - new String[]{ "1.0-spec" /* in java.net */, "1.0" /* in managed, and central */, - "1.0.1" /* in central */, "1.1" /* in managed */, "2.0-proposal-beta" - /* in java.net */, "2.0-spec" /* in java.net */, "2.0" - /* in central, and java.net */, "2.0.1" /* in java.net */, "2.1" - /* in managed */, "3.0" /* in central */, "3.1" /* in central */ }, "3.1", - "3.1" ); - } - - @Test - public void testUpdateProjectSimpleYetIncomplete() - throws Exception - { - assertUpdatedProjectMetadata( "incomplete_metadata_a", new String[]{ "1.0" }, "1.0", "1.0" ); - } - - @Test - public void testUpdateProjectSimpleYetMissing() - throws Exception - { - assertUpdatedProjectMetadata( "missing_metadata_a", new String[]{ "1.0" }, "1.0", "1.0" ); - } - - @Test - public void testUpdateVersionSimple10() - throws Exception - { - assertUpdatedReleaseVersionMetadata( "missing_metadata_a", "1.0" ); - } - - @Test - public void testUpdateVersionSimple20() - throws Exception - { - assertUpdatedReleaseVersionMetadata( "missing_metadata_b", "2.0" ); - } - - @Test - public void testUpdateVersionSimple20NotSnapshot() - throws Exception - { - assertUpdatedReleaseVersionMetadata( "missing_metadata_b", "2.0-20070821-dev" ); - } - - @Test - public void testUpdateVersionSnapshotA() - throws Exception - { - assertUpdatedSnapshotVersionMetadata( "snap_shots_a", "1.0-alpha-11-SNAPSHOT", "20070316", "175232", "11" ); - } - - @Test - public void testToPathFromVersionReference() - { - ItemSelector selector = ArchivaItemSelector.builder( ) - .withNamespace( "com.foo" ) - .withArtifactId( "foo-tool" ) - .withProjectId( "foo-tool" ) - .withVersion( "1.0" ).build( ); - - assertEquals( "com/foo/foo-tool/1.0/maven-metadata.xml", tools.toPath( selector ) ); - } - - @Test - public void testToPathFromProjectReference() - { - ItemSelector selector = ArchivaItemSelector.builder( ) - .withNamespace( "com.foo" ) - .withProjectId( "foo-tool" ) - .withArtifactId( "foo-tool" ).build( ); - - assertEquals( "com/foo/foo-tool/maven-metadata.xml", tools.toPath( selector ) ); - } - - @Test - public void testToProjectReferenceFooTools() - throws RepositoryMetadataException - { - assertProjectReference( "com.foo", "foo-tools", "com/foo/foo-tools/maven-metadata.xml" ); - } - - @Test - public void testToProjectReferenceAReallyLongPath() - throws RepositoryMetadataException - { - String groupId = "net.i.have.a.really.long.path.just.for.the.hell.of.it"; - String artifactId = "a"; - String path = "net/i/have/a/really/long/path/just/for/the/hell/of/it/a/maven-metadata.xml"; - - assertProjectReference( groupId, artifactId, path ); - } - - @Test - public void testToProjectReferenceCommonsLang() - throws RepositoryMetadataException - { - String groupId = "commons-lang"; - String artifactId = "commons-lang"; - String path = "commons-lang/commons-lang/maven-metadata.xml"; - - assertProjectReference( groupId, artifactId, path ); - } - - private void assertProjectReference( String groupId, String artifactId, String path ) - throws RepositoryMetadataException - { - ItemSelector reference = tools.toProjectSelector( path ); - - assertNotNull( "Reference should not be null.", reference ); - assertEquals( "ProjectReference.groupId", groupId, reference.getNamespace() ); - assertEquals( "ProjectReference.artifactId", artifactId, reference.getArtifactId() ); - } - - @Test - public void testToVersionedReferenceFooTool() - throws RepositoryMetadataException - { - String groupId = "com.foo"; - String artifactId = "foo-tool"; - String version = "1.0"; - String path = "com/foo/foo-tool/1.0/maven-metadata.xml"; - - assertVersionedReference( groupId, artifactId, version, path ); - } - - @Test - public void testToVersionedReferenceAReallyLongPath() - throws RepositoryMetadataException - { - String groupId = "net.i.have.a.really.long.path.just.for.the.hell.of.it"; - String artifactId = "a"; - String version = "1.1-alpha-1"; - String path = "net/i/have/a/really/long/path/just/for/the/hell/of/it/a/1.1-alpha-1/maven-metadata.xml"; - - assertVersionedReference( groupId, artifactId, version, path ); - } - - @Test - public void testToVersionedReferenceCommonsLang() - throws RepositoryMetadataException - { - String groupId = "commons-lang"; - String artifactId = "commons-lang"; - String version = "2.1"; - String path = "commons-lang/commons-lang/2.1/maven-metadata.xml"; - - assertVersionedReference( groupId, artifactId, version, path ); - } - - @Test - public void testToVersionedReferenceSnapshot() - throws RepositoryMetadataException - { - String groupId = "com.foo"; - String artifactId = "foo-connector"; - String version = "2.1-SNAPSHOT"; - String path = "com/foo/foo-connector/2.1-SNAPSHOT/maven-metadata.xml"; - - assertVersionedReference( groupId, artifactId, version, path ); - } - - private void assertVersionedReference( String groupId, String artifactId, String version, String path ) - throws RepositoryMetadataException - { - ItemSelector reference = tools.toVersionedSelector( path ); - assertNotNull( "Reference should not be null.", reference ); - - assertEquals( "VersionedReference.groupId", groupId, reference.getNamespace() ); - assertEquals( "VersionedReference.artifactId", artifactId, reference.getArtifactId() ); - assertEquals( "VersionedReference.version", version, reference.getVersion() ); - } - - private void assertSnapshotVersions( String artifactId, String version, String[] expectedVersions ) - throws Exception - { - Path repoRootDir = getRepositoryPath( "metadata-repository" ); - - ItemSelector reference = ArchivaItemSelector.builder( ) - .withNamespace( "org.apache.archiva.metadata.tests" ) - .withArtifactId( artifactId ) - .withProjectId( artifactId ) - .withVersion( version ).build( ); - - MavenManagedRepository repo = - createRepository( "test-repo", "Test Repository: " + name.getMethodName(), repoRootDir ); - - RepositoryContentProvider provider = applicationContext.getBean( "repositoryContentProvider#maven", RepositoryContentProvider.class ); - - ManagedRepositoryContent repoContent = - provider.createManagedContent( repo ); - - Set testedVersionSet = tools.gatherSnapshotVersions( repoContent, reference ); - - // Sort the list (for asserts) - List testedVersions = new ArrayList<>(); - testedVersions.addAll( testedVersionSet ); - Collections.sort( testedVersions, new VersionComparator() ); - - // Test the expected array of versions, to the actual tested versions - assertEquals( "Assert Snapshot Versions: length/size", expectedVersions.length, testedVersions.size() ); - - for ( int i = 0; i < expectedVersions.length; i++ ) - { - String actualVersion = testedVersions.get( i ); - assertEquals( "Snapshot Versions[" + i + "]", expectedVersions[i], actualVersion ); - } - } - - private void assertProjectMetadata( String expectedMetadata, ManagedRepositoryContent repository, - ItemSelector reference ) - throws LayoutException, IOException, SAXException, ParserConfigurationException - { - Path metadataFile = repository.getRepository().getRoot().getFilePath().resolve(tools.toPath( reference ) ); - String actualMetadata = org.apache.archiva.common.utils.FileUtils.readFileToString( metadataFile, Charset.defaultCharset() ); - - Diff detailedDiff = DiffBuilder.compare( expectedMetadata ).withTest( actualMetadata ).checkForSimilar().build(); - if ( detailedDiff.hasDifferences() ) - { - for ( Difference diff : detailedDiff.getDifferences() ) { - System.out.println( diff ); - } - // If it isn't similar, dump the difference. - assertEquals( expectedMetadata, actualMetadata ); - } - } - - private void assertMetadata( String expectedMetadata, ManagedRepositoryContent repository, - ItemSelector reference ) - throws LayoutException, IOException, SAXException, ParserConfigurationException - { - Path metadataFile = repository.getRepository().getRoot().getFilePath().resolve( tools.toPath( reference ) ); - String actualMetadata = org.apache.archiva.common.utils.FileUtils.readFileToString( metadataFile, Charset.defaultCharset() ); - - Diff detailedDiff = DiffBuilder.compare( expectedMetadata ).withTest( actualMetadata ).checkForSimilar().build(); - if ( detailedDiff.hasDifferences() ) - { - for ( Difference diff : detailedDiff.getDifferences() ) { - System.out.println( diff ); - } - // If it isn't similar, dump the difference. - assertEquals( expectedMetadata, actualMetadata ); - } - } - - private void assertMetadataPath( String expected, String actual ) - { - assertEquals( "Repository Specific Metadata Path", expected, actual ); - } - - private void assertUpdatedProjectMetadata( String artifactId, String[] expectedVersions, String latestVersion, - String releaseVersion ) - throws Exception - { - ManagedRepositoryContent testRepo = createTestRepoContent(); - ItemSelector reference = ArchivaItemSelector.builder( ) - .withNamespace( "org.apache.archiva.metadata.tests" ) - .withProjectId( artifactId ).build(); - - prepProjectTestRepo( testRepo, reference ); - - tools.updateProjectMetadata( testRepo, reference ); - - StringBuilder buf = new StringBuilder(); - buf.append( "\n" ); - buf.append( " " ).append( reference.getNamespace() ).append( "\n" ); - buf.append( " " ).append( reference.getProjectId() ).append( "\n" ); - // buf.append( " 1.0\n" ); - - if ( expectedVersions != null ) - { - buf.append( " \n" ); - if ( latestVersion != null ) - { - buf.append( " " ).append( latestVersion ).append( "\n" ); - } - if ( releaseVersion != null ) - { - buf.append( " " ).append( releaseVersion ).append( "\n" ); - } - - buf.append( " \n" ); - for ( int i = 0; i < expectedVersions.length; i++ ) - { - buf.append( " " ).append( expectedVersions[i] ).append( "\n" ); - } - buf.append( " \n" ); - buf.append( " \n" ); - } - buf.append( "" ); - - assertProjectMetadata( buf.toString(), testRepo, reference ); - } - - private void assertProjectMetadata( ManagedRepositoryContent testRepo, ItemSelector reference, - String artifactId, String[] expectedVersions, String latestVersion, - String releaseVersion ) - throws Exception - { - StringBuilder buf = new StringBuilder(); - buf.append( "\n" ); - buf.append( " " ).append( reference.getNamespace() ).append( "\n" ); - buf.append( " " ).append( reference.getProjectId() ).append( "\n" ); - - if ( expectedVersions != null ) - { - buf.append( " \n" ); - if ( latestVersion != null ) - { - buf.append( " " ).append( latestVersion ).append( "\n" ); - } - if ( releaseVersion != null ) - { - buf.append( " " ).append( releaseVersion ).append( "\n" ); - } - - buf.append( " \n" ); - for ( int i = 0; i < expectedVersions.length; i++ ) - { - buf.append( " " ).append( expectedVersions[i] ).append( "\n" ); - } - buf.append( " \n" ); - buf.append( " \n" ); - } - buf.append( "" ); - - assertProjectMetadata( buf.toString(), testRepo, reference ); - } - - - private void assertUpdatedReleaseVersionMetadata( String artifactId, String version ) - throws Exception - { - ManagedRepositoryContent testRepo = createTestRepoContent(); - - ItemSelector selector = ArchivaItemSelector.builder() - .withNamespace( "org.apache.archiva.metadata.tests" ) - .withProjectId( artifactId ) - .withArtifactId( artifactId ) - .withVersion( version ).build(); - - prepTestRepo( testRepo, selector ); - - tools.updateVersionMetadata( testRepo, selector ); - - StringBuilder buf = new StringBuilder(); - buf.append( "\n" ); - buf.append( " " ).append( selector.getNamespace() ).append( "\n" ); - buf.append( " " ).append( selector.getArtifactId() ).append( "\n" ); - buf.append( " " ).append( selector.getVersion() ).append( "\n" ); - buf.append( "" ); - - assertMetadata( buf.toString(), testRepo, selector ); - } - - private void assertUpdatedSnapshotVersionMetadata( String artifactId, String version, String expectedDate, - String expectedTime, String expectedBuildNumber ) - throws Exception - { - ManagedRepositoryContent testRepo = createTestRepoContent(); - ItemSelector reference = ArchivaItemSelector.builder() - .withNamespace( "org.apache.archiva.metadata.tests" ) - .withArtifactId( artifactId ) - .withProjectId( artifactId ) - .withVersion( version ).build(); - - prepTestRepo( testRepo, reference ); - - tools.updateVersionMetadata( testRepo, reference ); - - StringBuilder buf = new StringBuilder(); - buf.append( "\n" ); - buf.append( " " ).append( reference.getNamespace() ).append( "\n" ); - buf.append( " " ).append( reference.getArtifactId() ).append( "\n" ); - buf.append( " " ).append( reference.getVersion() ).append( "\n" ); - buf.append( " \n" ); - buf.append( " \n" ); - buf.append( " " ).append( expectedBuildNumber ).append( "\n" ); - buf.append( " " ); - buf.append( expectedDate ).append( "." ).append( expectedTime ); - buf.append( "\n" ); - buf.append( " \n" ); - buf.append( " " ).append( expectedDate ).append( expectedTime ).append( "\n" ); - buf.append( " \n" ); - buf.append( "" ); - - assertMetadata( buf.toString(), testRepo, reference ); - } - - private void removeProxyConnector( String sourceRepoId, String targetRepoId ) - { - ProxyConnectorConfiguration toRemove = null; - for ( ProxyConnectorConfiguration pcc : config.getConfiguration().getProxyConnectors() ) - { - if ( pcc.getTargetRepoId().equals( targetRepoId ) && pcc.getSourceRepoId().equals( sourceRepoId ) ) - { - toRemove = pcc; - } - } - if ( toRemove != null ) - { - config.getConfiguration().removeProxyConnector( toRemove ); - String prefix = "proxyConnectors.proxyConnector(" + "1" + ")"; // XXX - config.triggerChange( prefix + ".sourceRepoId", toRemove.getSourceRepoId() ); - config.triggerChange( prefix + ".targetRepoId", toRemove.getTargetRepoId() ); - config.triggerChange( prefix + ".proxyId", toRemove.getProxyId() ); - config.triggerChange( prefix + ".policies.releases", toRemove.getPolicy( "releases", "" ) ); - config.triggerChange( prefix + ".policies.checksum", toRemove.getPolicy( "checksum", "" ) ); - config.triggerChange( prefix + ".policies.snapshots", toRemove.getPolicy( "snapshots", "" ) ); - config.triggerChange( prefix + ".policies.cache-failures", toRemove.getPolicy( "cache-failures", "" ) ); - } - } - - private void createProxyConnector( String sourceRepoId, String targetRepoId ) - { - ProxyConnectorConfiguration connectorConfig = new ProxyConnectorConfiguration(); - connectorConfig.setSourceRepoId( sourceRepoId ); - connectorConfig.setTargetRepoId( targetRepoId ); - connectorConfig.addPolicy( ProxyConnectorConfiguration.POLICY_CHECKSUM, ChecksumPolicy.IGNORE.getId() ); - connectorConfig.addPolicy( ProxyConnectorConfiguration.POLICY_RELEASES, ReleasesPolicy.ALWAYS.getId() ); - connectorConfig.addPolicy( ProxyConnectorConfiguration.POLICY_SNAPSHOTS, SnapshotsPolicy.ALWAYS.getId() ); - connectorConfig.addPolicy( ProxyConnectorConfiguration.POLICY_CACHE_FAILURES, CachedFailuresPolicy.NO.getId() ); - - int count = config.getConfiguration().getProxyConnectors().size(); - config.getConfiguration().addProxyConnector( connectorConfig ); - - // Proper Triggering ... - String prefix = "proxyConnectors.proxyConnector(" + count + ")"; - config.triggerChange( prefix + ".sourceRepoId", connectorConfig.getSourceRepoId() ); - config.triggerChange( prefix + ".targetRepoId", connectorConfig.getTargetRepoId() ); - config.triggerChange( prefix + ".proxyId", connectorConfig.getProxyId() ); - config.triggerChange( prefix + ".policies.releases", connectorConfig.getPolicy( "releases", "" ) ); - config.triggerChange( prefix + ".policies.checksum", connectorConfig.getPolicy( "checksum", "" ) ); - config.triggerChange( prefix + ".policies.snapshots", connectorConfig.getPolicy( "snapshots", "" ) ); - config.triggerChange( prefix + ".policies.cache-failures", connectorConfig.getPolicy( "cache-failures", "" ) ); - } - - private ManagedRepositoryContent createTestRepoContent() - throws Exception - { - Path repoRoot = Paths.get( "target/metadata-tests/" + name.getMethodName() ); - if ( Files.exists(repoRoot) ) - { - org.apache.archiva.common.utils.FileUtils.deleteDirectory( repoRoot ); - } - - Files.createDirectories(repoRoot); - - MavenManagedRepository repoConfig = - createRepository( "test-repo", "Test Repository: " + name.getMethodName(), repoRoot ); - - RepositoryContentProvider provider = applicationContext.getBean( "repositoryContentProvider#maven", RepositoryContentProvider.class ); - - ManagedRepositoryContent repoContent = - provider.createManagedContent( repoConfig ); - return repoContent; - } - - private void prepProjectTestRepo( ManagedRepositoryContent repo, ItemSelector reference) - throws IOException - { - String groupDir = StringUtils.replaceChars( reference.getNamespace(), '.', '/' ); - String path = groupDir + "/" + reference.getArtifactId(); - - Path srcRepoDir = getRepositoryPath( "metadata-repository" ); - Path srcDir = srcRepoDir.resolve( path ); - Path destDir = repo.getRepository().getRoot().getFilePath().resolve( path ); - - assertTrue( "Source Dir exists: " + srcDir, Files.exists(srcDir) ); - Files.createDirectories(destDir); - - FileUtils.copyDirectory( srcDir.toFile(), destDir.toFile() ); - } - - private void prepTestRepo( ManagedRepositoryContent repo, ItemSelector reference ) - throws IOException - { - String groupDir = StringUtils.replaceChars( reference.getNamespace(), '.', '/' ); - String path = groupDir + "/" + reference.getArtifactId(); - - Path srcRepoDir = getRepositoryPath( "metadata-repository" ); - Path srcDir = srcRepoDir.resolve( path ); - Path destDir = repo.getRepository().getRoot().getFilePath().resolve( path ); - - assertTrue( "Source Dir exists: " + srcDir, Files.exists(srcDir) ); - Files.createDirectories(destDir); - - FileUtils.copyDirectory( srcDir.toFile(), destDir.toFile() ); - } - - -} diff --git a/archiva-modules/archiva-maven/archiva-maven-repository/src/test/java/org/apache/archiva/repository/maven/metadata/RepositoryMetadataReaderTest.java b/archiva-modules/archiva-maven/archiva-maven-repository/src/test/java/org/apache/archiva/repository/maven/metadata/RepositoryMetadataReaderTest.java deleted file mode 100644 index 34799465a..000000000 --- a/archiva-modules/archiva-maven/archiva-maven-repository/src/test/java/org/apache/archiva/repository/maven/metadata/RepositoryMetadataReaderTest.java +++ /dev/null @@ -1,94 +0,0 @@ -package org.apache.archiva.repository.maven.metadata; - -/* - * 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.maven.metadata.MavenMetadataReader; -import org.apache.archiva.model.ArchivaRepositoryMetadata; -import org.apache.archiva.repository.metadata.RepositoryMetadataException; -import org.apache.archiva.test.utils.ArchivaBlockJUnit4ClassRunner; -import org.junit.Test; -import org.junit.runner.RunWith; - -import java.net.URISyntaxException; -import java.nio.file.Path; -import java.nio.file.Paths; - -/** - * RepositoryMetadataReaderTest - * - * - */ -@RunWith( ArchivaBlockJUnit4ClassRunner.class ) -public class RepositoryMetadataReaderTest - extends TestCase -{ - - private Path getRepositoryPath(String repoName) { - try - { - return Paths.get( Thread.currentThread( ).getContextClassLoader( ).getResource( "repositories/" + repoName ).toURI( ) ); - } - catch ( URISyntaxException e ) - { - throw new RuntimeException( "Could not resolve repository path " + e.getMessage( ), e ); - } - } - - @Test - public void testLoadSimple() - throws RepositoryMetadataException - { - Path defaultRepoDir = getRepositoryPath( "default-repository" ); - Path metadataFile = defaultRepoDir.resolve( "org/apache/maven/shared/maven-downloader/maven-metadata.xml" ); - - MavenMetadataReader metadataReader = new MavenMetadataReader( ); - - ArchivaRepositoryMetadata metadata = metadataReader.read( metadataFile ); - - assertNotNull( metadata ); - assertEquals( "Group Id", "org.apache.maven.shared", metadata.getGroupId() ); - assertEquals( "Artifact Id", "maven-downloader", metadata.getArtifactId() ); - assertEquals( "Released Version", "1.1", metadata.getReleasedVersion() ); - assertEquals( "List of Available Versions", 2, metadata.getAvailableVersions().size() ); - assertTrue( "Available version 1.0", metadata.getAvailableVersions().contains( "1.0" ) ); - assertTrue( "Available version 1.1", metadata.getAvailableVersions().contains( "1.1" ) ); - } - - @Test - public void testLoadComplex() - throws RepositoryMetadataException - { - Path defaultRepoDir = getRepositoryPath( "default-repository" ); - Path metadataFile = defaultRepoDir.resolve( "org/apache/maven/samplejar/maven-metadata.xml" ); - MavenMetadataReader metadataReader = new MavenMetadataReader( ); - - ArchivaRepositoryMetadata metadata = metadataReader.read( metadataFile ); - - assertNotNull( metadata ); - assertEquals( "Group Id", "org.apache.maven", metadata.getGroupId() ); - assertEquals( "Artifact Id", "samplejar", metadata.getArtifactId() ); - assertEquals( "Released Version", "2.0", metadata.getReleasedVersion() ); - assertEquals( "Latest Version", "6.0-SNAPSHOT", metadata.getLatestVersion() ); - assertEquals( "List of Available Versions", 18, metadata.getAvailableVersions().size() ); - assertTrue( "Available version 6.0-20060311.183228-10", - metadata.getAvailableVersions().contains( "6.0-20060311.183228-10" ) ); - assertTrue( "Available version 6.0-SNAPSHOT", metadata.getAvailableVersions().contains( "6.0-SNAPSHOT" ) ); - } -} diff --git a/archiva-modules/archiva-maven/archiva-maven-repository/src/test/java/org/apache/archiva/repository/maven/metadata/RepositoryMetadataWriterTest.java b/archiva-modules/archiva-maven/archiva-maven-repository/src/test/java/org/apache/archiva/repository/maven/metadata/RepositoryMetadataWriterTest.java deleted file mode 100644 index b02c5116d..000000000 --- a/archiva-modules/archiva-maven/archiva-maven-repository/src/test/java/org/apache/archiva/repository/maven/metadata/RepositoryMetadataWriterTest.java +++ /dev/null @@ -1,76 +0,0 @@ -package org.apache.archiva.repository.maven.metadata; - -/* - * 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.model.ArchivaRepositoryMetadata; -import org.apache.archiva.repository.metadata.base.RepositoryMetadataWriter; -import org.apache.archiva.test.utils.ArchivaBlockJUnit4ClassRunner; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.xmlunit.assertj.XmlAssert; - -import java.io.StringWriter; -import java.net.URISyntaxException; -import java.nio.charset.Charset; -import java.nio.file.Path; -import java.nio.file.Paths; - -/** - * RepositoryMetadataWriterTest - */ -@RunWith ( ArchivaBlockJUnit4ClassRunner.class ) -public class RepositoryMetadataWriterTest - extends TestCase -{ - private Path getRepositoryPath(String repoName) { - try - { - return Paths.get( Thread.currentThread( ).getContextClassLoader( ).getResource( "repositories/" + repoName ).toURI( ) ); - } - catch ( URISyntaxException e ) - { - throw new RuntimeException( "Could not resolve repository path " + e.getMessage( ), e ); - } - } - - @Test - public void testWriteSimple() - throws Exception - { - Path defaultRepoDir = getRepositoryPath( "default-repository" ); - Path expectedFile = defaultRepoDir.resolve( "org/apache/maven/shared/maven-downloader/maven-metadata.xml" ); - String expectedContent = org.apache.archiva.common.utils.FileUtils.readFileToString( expectedFile, Charset.defaultCharset() ); - - ArchivaRepositoryMetadata metadata = new ArchivaRepositoryMetadata(); - - metadata.setGroupId( "org.apache.maven.shared" ); - metadata.setArtifactId( "maven-downloader" ); - metadata.setVersion( "1.0" ); - metadata.setReleasedVersion( "1.1" ); - metadata.getAvailableVersions().add( "1.0" ); - metadata.getAvailableVersions().add( "1.1" ); - metadata.setLastUpdated( "20061212214311" ); - - StringWriter actual = new StringWriter(); - RepositoryMetadataWriter.write( metadata, actual ); - - XmlAssert.assertThat( actual.toString() ).and( expectedContent ).areIdentical(); - } -} diff --git a/archiva-modules/archiva-maven/archiva-maven-repository/src/test/java/org/apache/archiva/repository/maven/metadata/storage/Maven2RepositoryMetadataResolverMRM1411RepoGroupTest.java b/archiva-modules/archiva-maven/archiva-maven-repository/src/test/java/org/apache/archiva/repository/maven/metadata/storage/Maven2RepositoryMetadataResolverMRM1411RepoGroupTest.java deleted file mode 100644 index 742631588..000000000 --- a/archiva-modules/archiva-maven/archiva-maven-repository/src/test/java/org/apache/archiva/repository/maven/metadata/storage/Maven2RepositoryMetadataResolverMRM1411RepoGroupTest.java +++ /dev/null @@ -1,555 +0,0 @@ -package org.apache.archiva.repository.maven.metadata.storage; - -/* - * 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.configuration.ArchivaConfiguration; -import org.apache.archiva.configuration.Configuration; -import org.apache.archiva.configuration.ManagedRepositoryConfiguration; -import org.apache.archiva.configuration.ProxyConnectorConfiguration; -import org.apache.archiva.configuration.RemoteRepositoryConfiguration; -import org.apache.archiva.configuration.RepositoryGroupConfiguration; -import org.apache.archiva.filter.AllFilter; -import org.apache.archiva.filter.Filter; -import org.apache.archiva.metadata.model.ArtifactMetadata; -import org.apache.archiva.metadata.model.Dependency; -import org.apache.archiva.metadata.model.License; -import org.apache.archiva.metadata.model.MailingList; -import org.apache.archiva.metadata.model.ProjectVersionMetadata; -import org.apache.archiva.metadata.repository.storage.ReadMetadataRequest; -import org.apache.archiva.maven.common.proxy.WagonFactory; -import org.apache.archiva.maven.common.proxy.WagonFactoryRequest; -import org.apache.archiva.repository.RepositoryRegistry; -import org.apache.archiva.repository.base.RepositoryHandlerDependencies; -import org.apache.archiva.test.utils.ArchivaSpringJUnit4ClassRunner; -import org.apache.commons.io.FileUtils; -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 javax.inject.Inject; -import javax.inject.Named; -import java.io.IOException; -import java.nio.file.Files; -import java.nio.file.Path; -import java.nio.file.Paths; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.List; - -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.when; - - -@RunWith ( ArchivaSpringJUnit4ClassRunner.class ) -@ContextConfiguration ( { "classpath*:/META-INF/spring-context.xml", "classpath:/spring-context.xml" } ) -public class Maven2RepositoryMetadataResolverMRM1411RepoGroupTest - extends TestCase -{ - private static final Filter ALL = new AllFilter(); - - @Inject - @Named ( "repositoryStorage#maven2") - private Maven2RepositoryStorage storage; - - private static final String TEST_REPO_ID = "test"; - - private static final String TEST_SNAP_REPO_ID = "tests"; - - private static final String TEST_REPO_GROUP_ID = "testrg"; - - 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"; - - @Inject - @Named ( "archivaConfiguration#default" ) - private ArchivaConfiguration configuration; - - @Inject - RepositoryRegistry repositoryRegistry; - - @SuppressWarnings( "unused" ) - @Inject - RepositoryHandlerDependencies repositoryHandlerDependencies; - - - private WagonFactory wagonFactory; - - ManagedRepositoryConfiguration testRepo; - - ManagedRepositoryConfiguration testRepoS; - - Configuration c; - - @Before - @Override - public void setUp() - throws Exception - { - super.setUp(); - - c = new Configuration(); - - testRepo = new ManagedRepositoryConfiguration(); - testRepo.setId( TEST_REPO_ID ); - testRepo.setLocation( Paths.get( "target/test-repository" ).toAbsolutePath().toString() ); - testRepo.setReleases( true ); - testRepo.setSnapshots( false ); - c.addManagedRepository( testRepo ); - - testRepoS = new ManagedRepositoryConfiguration(); - testRepoS.setId( TEST_SNAP_REPO_ID ); - testRepoS.setLocation( Paths.get( "target/test-repositorys" ).toAbsolutePath().toString() ); - testRepoS.setReleases( false ); - testRepoS.setSnapshots( true ); - c.addManagedRepository( testRepoS ); - - 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 ); - - ProxyConnectorConfiguration proxyConnectors = new ProxyConnectorConfiguration(); - proxyConnectors.setSourceRepoId( TEST_SNAP_REPO_ID ); - proxyConnectors.setTargetRepoId( TEST_REMOTE_REPO_ID ); - proxyConnectors.setDisabled( false ); - c.addProxyConnector( proxyConnectors ); - - List repos = new ArrayList<>(); - repos.add( TEST_REPO_ID ); - repos.add( TEST_SNAP_REPO_ID ); - - RepositoryGroupConfiguration repoGroup = new RepositoryGroupConfiguration(); - repoGroup.setId( TEST_REPO_GROUP_ID ); - repoGroup.setRepositories( repos ); - c.addRepositoryGroup( repoGroup ); - - configuration.save( c ); - repositoryRegistry.reload(); - - assertFalse( c.getManagedRepositories().get( 0 ).isSnapshots() ); - assertTrue( c.getManagedRepositories().get( 0 ).isReleases() ); - - assertTrue( c.getManagedRepositories().get( 1 ).isSnapshots() ); - assertFalse( c.getManagedRepositories().get( 1 ).isReleases() ); - - wagonFactory = mock( WagonFactory.class ); - - storage.setWagonFactory( wagonFactory ); - - Wagon wagon = new MockWagon(); - when( wagonFactory.getWagon( new WagonFactoryRequest().protocol( "wagon#http" ) ) ).thenReturn( wagon ); - } - - // Tests for MRM-1411 - START - @Test - public void testGetProjectVersionMetadataWithParentSuccessful() - throws Exception - { - copyTestArtifactWithParent( "src/test/resources/com/example/test/test-artifact-module-a", - "target/test-repository/com/example/test/test-artifact-module-a" ); - copyTestArtifactWithParent( "src/test/resources/com/example/test/test-artifact-root", - "target/test-repository/com/example/test/test-artifact-root" ); - copyTestArtifactWithParent( "src/test/resources/com/example/test/test-artifact-parent", - "target/test-repository/com/example/test/test-artifact-parent" ); - - ReadMetadataRequest readMetadataRequest = - new ReadMetadataRequest().repositoryId( TEST_REPO_ID ).namespace( "com.example.test" ).projectId( - "test-artifact-module-a" ).projectVersion( "1.0" ); - ProjectVersionMetadata metadata = storage.readProjectVersionMetadata( readMetadataRequest ); - - 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 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" ); - - List paths = new ArrayList<>(); - paths.add( "target/test-repository/com/example/test/test-artifact-module-a" ); - paths.add( "target/test-repository/com/example/test/test-artifact-parent" ); - paths.add( "target/test-repository/com/example/test/test-artifact-root" ); - - deleteTestArtifactWithParent( paths ); - } - - @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( "src/test/resources/com/example/test/test-artifact-module-a", - "target/test-repository/com/example/test/test-artifact-module-a" ); - copyTestArtifactWithParent( "src/test/resources/com/example/test/test-artifact-root", - "target/test-repository/com/example/test/test-artifact-root" ); - copyTestArtifactWithParent( "src/test/resources/com/example/test/test-artifact-parent", - "target/test-repository/com/example/test/test-artifact-parent" ); - - ReadMetadataRequest readMetadataRequest = - new ReadMetadataRequest().repositoryId( TEST_REPO_ID ).namespace( "com.example.test" ).projectId( - "test-artifact-module-a" ).projectVersion( "1.0" ); - ProjectVersionMetadata metadata = storage.readProjectVersionMetadata( readMetadataRequest ); - 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() ); - - List paths = new ArrayList<>(); - paths.add( "target/test-repository/com/example/test/test-artifact-module-a" ); - paths.add( "target/test-repository/com/example/test/test-artifact-parent" ); - paths.add( "target/test-repository/com/example/test/test-artifact-root" ); - - deleteTestArtifactWithParent( paths ); - } - - @Test - public void testGetProjectVersionMetadataWithParentNotInAnyRemoteRepo() - throws Exception - { - copyTestArtifactWithParent( "src/test/resources/com/example/test/test-artifact-module-a", - "target/test-repository/com/example/test/test-artifact-module-a" ); - - ReadMetadataRequest readMetadataRequest = - new ReadMetadataRequest().repositoryId( TEST_REPO_ID ).namespace( "com.example.test" ).projectId( - "missing-parent" ).projectVersion( "1.1" ); - - ProjectVersionMetadata metadata = storage.readProjectVersionMetadata( readMetadataRequest ); - - 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() ); - - List paths = new ArrayList<>(); - paths.add( "target/test-repository/com/example/test/test-artifact-module-a" ); - paths.add( "target/test-repository/com/example/test/test-artifact-parent" ); - paths.add( "target/test-repository/com/example/test/test-artifact-root" ); - - deleteTestArtifactWithParent( paths ); - } - - @Test - public void testGetProjectVersionMetadataWithParentSnapshotVersion() - throws Exception - { - copyTestArtifactWithParent( "target/test-classes/com/example/test/test-snapshot-artifact-module-a", - "target/test-repositorys/com/example/test/test-snapshot-artifact-module-a" ); - copyTestArtifactWithParent( "target/test-classes/com/example/test/test-snapshot-artifact-root", - "target/test-repositorys/com/example/test/test-snapshot-artifact-root" ); - copyTestArtifactWithParent( "src/test/resources/com/example/test/test-artifact-parent", - "target/test-repositorys/com/example/test/test-artifact-parent" ); - - ReadMetadataRequest readMetadataRequest = - new ReadMetadataRequest( TEST_SNAP_REPO_ID, "com.example.test", "test-snapshot-artifact-module-a", - "1.1-SNAPSHOT" ); - - ProjectVersionMetadata metadata = storage.readProjectVersionMetadata( readMetadataRequest ); - - MavenProjectFacet facet = (MavenProjectFacet) metadata.getFacet( MavenProjectFacet.FACET_ID ); - assertEquals( "jar", facet.getPackaging() ); - assertEquals( "com.example.test", facet.getParent().getGroupId() ); - assertEquals( "test-snapshot-artifact-root", facet.getParent().getArtifactId() ); - assertEquals( "1.1-SNAPSHOT", facet.getParent().getVersion() ); - assertEquals( "test-snapshot-artifact-module-a", facet.getArtifactId() ); - assertEquals( "com.example.test", facet.getGroupId() ); - assertNull( metadata.getCiManagement() ); - assertNotNull( metadata.getDescription() ); - - checkApacheLicense( metadata ); - - assertEquals( "1.1-SNAPSHOT", metadata.getId() ); - assertEquals( "Test Snapshot Artifact :: Module A", metadata.getName() ); - String path = "test-snapshot-artifact/trunk/test-snapshot-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 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" ); - - List paths = new ArrayList<>(); - paths.add( "target/test-repositorys/com/example/test/test-snapshot-artifact-module-a" ); - paths.add( "target/test-repositorys/com/example/test/test-snapshot-artifact-root" ); - deleteTestArtifactWithParent( paths ); - } - - @Test - public void testGetProjectVersionMetadataWithParentSnapshotVersionAndSnapNotAllowed() - throws Exception - { - copyTestArtifactWithParent( "target/test-classes/com/example/test/test-snapshot-artifact-module-a", - "target/test-repositorys/com/example/test/test-snapshot-artifact-module-a" ); - copyTestArtifactWithParent( "src/test/resources/com/example/test/test-artifact-parent", - "target/test-repositorys/com/example/test/test-artifact-parent" ); - copyTestArtifactWithParent( "src/test/resources/com/example/test/test-snapshot-artifact-root", - "target/test-repositorys/com/example/test/test-snapshot-artifact-root" ); - - ReadMetadataRequest readMetadataRequest = - new ReadMetadataRequest().repositoryId( TEST_SNAP_REPO_ID ).namespace( "com.example.test" ).projectId( - "test-snapshot-artifact-module-a" ).projectVersion( "1.1-SNAPSHOT" ); - ProjectVersionMetadata metadata = storage.readProjectVersionMetadata( readMetadataRequest ); - - MavenProjectFacet facet = (MavenProjectFacet) metadata.getFacet( MavenProjectFacet.FACET_ID ); - assertEquals( "jar", facet.getPackaging() ); - assertEquals( "com.example.test", facet.getParent().getGroupId() ); - assertEquals( "test-snapshot-artifact-root", facet.getParent().getArtifactId() ); - assertEquals( "1.1-SNAPSHOT", facet.getParent().getVersion() ); - assertEquals( "test-snapshot-artifact-module-a", facet.getArtifactId() ); - assertEquals( "com.example.test", facet.getGroupId() ); - assertNull( metadata.getCiManagement() ); - assertNotNull( metadata.getDescription() ); - - checkApacheLicense( metadata ); - - assertEquals( "1.1-SNAPSHOT", metadata.getId() ); - assertEquals( "Test Snapshot Artifact :: Module A", metadata.getName() ); - String path = "test-snapshot-artifact/trunk/test-snapshot-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 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" ); - - List paths = new ArrayList<>(); - paths.add( "target/test-repositorys/com/example/test/test-snapshot-artifact-module-a" ); - paths.add( "target/test-repositorys/com/example/test/test-snapshot-artifact-root" ); - - deleteTestArtifactWithParent( paths ); - } - - @Test - public void testGetProjectVersionMetadataWithParentSnapshotVersionAndSnapNotAllowed2() - throws Exception - { - copyTestArtifactWithParent( "src/test/resources/com/example/test/test-artifact-module-b", - "target/test-repository/com/example/test/test-artifact-module-b" ); - copyTestArtifactWithParent( "src/test/resources/com/example/test/test-artifact-parent", - "target/test-repository/com/example/test/test-artifact-parent" ); - copyTestArtifactWithParent( "src/test/resources/com/example/test/test-snapshot-artifact-root", - "target/test-repository/com/example/test/test-snapshot-artifact-root" ); - - ReadMetadataRequest readMetadataRequest = - new ReadMetadataRequest().repositoryId( TEST_REPO_ID ).namespace( "com.example.test" ).projectId( - "test-artifact-module-b" ).projectVersion( "1.0" ); - - ProjectVersionMetadata metadata = storage.readProjectVersionMetadata( readMetadataRequest ); - - MavenProjectFacet facet = (MavenProjectFacet) metadata.getFacet( MavenProjectFacet.FACET_ID ); - assertEquals( "jar", facet.getPackaging() ); - assertEquals( "com.example.test", facet.getParent().getGroupId() ); - assertEquals( "test-snapshot-artifact-root", facet.getParent().getArtifactId() ); - assertEquals( "1.1-SNAPSHOT", facet.getParent().getVersion() ); - assertEquals( "test-artifact-module-b", 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 B", metadata.getName() ); - String path = "test-snapshot-artifact/trunk/test-artifact-module-b"; - 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 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" ); - - List paths = new ArrayList<>(); - paths.add( "target/test-repository/com/example/test/test-artifact-module-b" ); - paths.add( "target/test-repository/com/example/test/test-snapshot-artifact-root" ); - - deleteTestArtifactWithParent( paths ); - } - // Tests for MRM-1411 - END - - private void assertDependency( Dependency dependency, String groupId, String artifactId, String version ) - { - assertDependency( dependency, groupId, artifactId, version, "compile" ); - } - - private void assertDependency( Dependency dependency, String groupId, String artifactId, String version, - String scope ) - { - assertEquals( artifactId, dependency.getArtifactId() ); - assertEquals( "jar", dependency.getType() ); - assertEquals( version, dependency.getVersion() ); - assertEquals( groupId, dependency.getNamespace() ); - assertEquals( scope, dependency.getScope() ); - assertNull( dependency.getClassifier() ); - assertNull( dependency.getSystemPath() ); - } - - private void assertArtifact( ArtifactMetadata artifact, String id, int size, String sha1, String md5 ) - { - assertEquals( id, artifact.getId() ); - assertEquals( md5, artifact.getMd5() ); - assertEquals( sha1, artifact.getSha1() ); - assertEquals( size, artifact.getSize() ); - assertEquals( "org.codehaus.plexus", artifact.getNamespace() ); - assertEquals( "plexus-spring", artifact.getProject() ); - assertEquals( "1.2", artifact.getVersion() ); - assertEquals( TEST_REPO_ID, artifact.getRepositoryId() ); - } - - private void assertMailingList( MailingList mailingList, String name, String archive, String post, String subscribe, - String unsubscribe, List otherArchives, boolean allowPost ) - { - assertEquals( archive, mailingList.getMainArchiveUrl() ); - if ( allowPost ) - { - assertEquals( post, mailingList.getPostAddress() ); - } - else - { - assertNull( mailingList.getPostAddress() ); - } - assertEquals( subscribe, mailingList.getSubscribeAddress() ); - assertEquals( unsubscribe, mailingList.getUnsubscribeAddress() ); - assertEquals( name, mailingList.getName() ); - assertEquals( otherArchives, mailingList.getOtherArchives() ); - } - - private void assertMailingList( String prefix, MailingList mailingList, String name, boolean allowPost, - String nabbleUrl ) - { - List otherArchives = new ArrayList<>(); - otherArchives.add( "http://www.mail-archive.com/" + prefix + "@archiva.apache.org" ); - if ( nabbleUrl != null ) - { - otherArchives.add( nabbleUrl ); - } - otherArchives.add( "http://markmail.org/list/org.apache.archiva." + prefix ); - assertMailingList( mailingList, name, "http://mail-archives.apache.org/mod_mbox/archiva-" + prefix + "/", - prefix + "@archiva.apache.org", prefix + "-subscribe@archiva.apache.org", - prefix + "-unsubscribe@archiva.apache.org", otherArchives, allowPost ); - } - - private void checkApacheLicense( ProjectVersionMetadata metadata ) - { - assertEquals( Arrays.asList( new License( "The Apache Software License, Version 2.0", - "http://www.apache.org/licenses/LICENSE-2.0.txt" ) ), - metadata.getLicenses() ); - } - - private void checkOrganizationApache( ProjectVersionMetadata metadata ) - { - assertEquals( "The Apache Software Foundation", metadata.getOrganization().getName() ); - assertEquals( "http://www.apache.org/", metadata.getOrganization().getUrl() ); - } - - private void deleteTestArtifactWithParent( List pathsToBeDeleted ) - throws IOException - { - for ( String path : pathsToBeDeleted ) - { - Path dir = Paths.get( org.apache.archiva.common.utils.FileUtils.getBasedir(), path ); - org.apache.archiva.common.utils.FileUtils.deleteDirectory( dir ); - - assertFalse( Files.exists(dir) ); - } - Path dest = Paths.get( org.apache.archiva.common.utils.FileUtils.getBasedir(), "target/test-repository/com/example/test/test-artifact-module-a" ); - Path parentPom = Paths.get( org.apache.archiva.common.utils.FileUtils.getBasedir(), "target/test-repository/com/example/test/test-artifact-parent" ); - Path rootPom = Paths.get( org.apache.archiva.common.utils.FileUtils.getBasedir(), "target/test-repository/com/example/test/test-artifact-root" ); - - org.apache.archiva.common.utils.FileUtils.deleteDirectory( dest ); - org.apache.archiva.common.utils.FileUtils.deleteDirectory( parentPom ); - org.apache.archiva.common.utils.FileUtils.deleteDirectory( rootPom ); - - assertFalse( Files.exists(dest) ); - assertFalse( Files.exists(parentPom) ); - assertFalse( Files.exists(rootPom) ); - } - - private Path copyTestArtifactWithParent( String srcPath, String destPath ) - throws IOException - { - Path src = Paths.get( org.apache.archiva.common.utils.FileUtils.getBasedir(), srcPath ); - Path dest = Paths.get( org.apache.archiva.common.utils.FileUtils.getBasedir(), destPath ); - - FileUtils.copyDirectory( src.toFile(), dest.toFile() ); - assertTrue( Files.exists(dest) ); - return dest; - } - -} diff --git a/archiva-modules/archiva-maven/archiva-maven-repository/src/test/java/org/apache/archiva/repository/maven/metadata/storage/Maven2RepositoryMetadataResolverMRM1411Test.java b/archiva-modules/archiva-maven/archiva-maven-repository/src/test/java/org/apache/archiva/repository/maven/metadata/storage/Maven2RepositoryMetadataResolverMRM1411Test.java deleted file mode 100644 index c7cc740d0..000000000 --- a/archiva-modules/archiva-maven/archiva-maven-repository/src/test/java/org/apache/archiva/repository/maven/metadata/storage/Maven2RepositoryMetadataResolverMRM1411Test.java +++ /dev/null @@ -1,459 +0,0 @@ -package org.apache.archiva.repository.maven.metadata.storage; - -/* - * 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.configuration.ArchivaConfiguration; -import org.apache.archiva.configuration.Configuration; -import org.apache.archiva.configuration.ManagedRepositoryConfiguration; -import org.apache.archiva.configuration.ProxyConnectorConfiguration; -import org.apache.archiva.configuration.RemoteRepositoryConfiguration; -import org.apache.archiva.filter.AllFilter; -import org.apache.archiva.filter.Filter; -import org.apache.archiva.metadata.model.ArtifactMetadata; -import org.apache.archiva.metadata.model.Dependency; -import org.apache.archiva.metadata.model.License; -import org.apache.archiva.metadata.model.MailingList; -import org.apache.archiva.metadata.model.ProjectVersionMetadata; -import org.apache.archiva.metadata.repository.storage.ReadMetadataRequest; -import org.apache.archiva.metadata.repository.storage.RepositoryStorageRuntimeException; -import org.apache.archiva.maven.common.proxy.WagonFactory; -import org.apache.archiva.maven.common.proxy.WagonFactoryRequest; -import org.apache.archiva.repository.ReleaseScheme; -import org.apache.archiva.repository.RepositoryRegistry; -import org.apache.archiva.repository.base.RepositoryHandlerDependencies; -import org.apache.archiva.test.utils.ArchivaSpringJUnit4ClassRunner; -import org.apache.commons.io.FileUtils; -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 javax.inject.Inject; -import javax.inject.Named; -import java.io.IOException; -import java.nio.file.Files; -import java.nio.file.Path; -import java.nio.file.Paths; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.HashMap; -import java.util.List; - -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.when; - -@RunWith ( ArchivaSpringJUnit4ClassRunner.class ) -@ContextConfiguration ( { "classpath*:/META-INF/spring-context.xml", "classpath:/spring-context.xml" } ) -public class Maven2RepositoryMetadataResolverMRM1411Test - extends TestCase -{ - private static final Filter ALL = new AllFilter(); - - @Inject - @Named ( "repositoryStorage#maven2") - private Maven2RepositoryStorage storage; - - 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"; - - @Inject - @Named ( "archivaConfiguration#default" ) - private ArchivaConfiguration configuration; - - @Inject - RepositoryRegistry repositoryRegistry; - - @SuppressWarnings( "unused" ) - @Inject - RepositoryHandlerDependencies repositoryHandlerDependencies; - - - private WagonFactory wagonFactory; - - ManagedRepositoryConfiguration testRepo; - - Configuration c; - - @Before - @Override - public void setUp() - throws Exception - { - super.setUp(); - - c = new Configuration(); - testRepo = new ManagedRepositoryConfiguration(); - testRepo.setId( TEST_REPO_ID ); - testRepo.setLocation( Paths.get( "target/test-repository" ).toAbsolutePath().toString() ); - testRepo.setReleases( true ); - testRepo.setSnapshots( true ); - 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 ); - - repositoryRegistry.reload(); - - assertTrue( c.getManagedRepositories().get( 0 ).isSnapshots() ); - assertTrue( c.getManagedRepositories().get( 0 ).isReleases() ); - - wagonFactory = mock( WagonFactory.class ); - - assertNotNull( storage ); - storage.setWagonFactory( wagonFactory ); - - Wagon wagon = new MockWagon(); - when( wagonFactory.getWagon( - new WagonFactoryRequest( "wagon#http", new HashMap() ) ) ).thenReturn( wagon ); - } - - // Tests for MRM-1411 - START - @Test - public void testGetProjectVersionMetadataWithParentSuccessful() - throws Exception - { - assertNotNull( storage ); - copyTestArtifactWithParent( "target/test-classes/com/example/test/test-artifact-module-a", - "target/test-repository/com/example/test/test-artifact-module-a" ); - copyTestArtifactWithParent( "src/test/resources/com/example/test/test-artifact-parent", - "target/test-repository/com/example/test/test-artifact-parent" ); - - copyTestArtifactWithParent( "target/test-classes/com/example/test/test-artifact-root", - "target/test-repository/com/example/test/test-artifact-root" ); - - ProjectVersionMetadata metadata = storage.readProjectVersionMetadata( - new ReadMetadataRequest( 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 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" ); - - List paths = new ArrayList<>(); - paths.add( "target/test-repository/com/example/test/test-artifact-module-a" ); - paths.add( "target/test-repository/com/example/test/test-artifact-parent" ); - paths.add( "target/test-repository/com/example/test/test-artifact-root" ); - - deleteTestArtifactWithParent( paths ); - } - - @Test - public void testGetProjectVersionMetadataWithParentNoRemoteReposConfigured() - throws Exception - { - assertNotNull( storage ); - // remove configuration - Configuration config = configuration.getConfiguration(); - RemoteRepositoryConfiguration remoteRepo = config.findRemoteRepositoryById( TEST_REMOTE_REPO_ID ); - config.removeRemoteRepository( remoteRepo ); - - configuration.save( config ); - assertNotNull( storage ); - - copyTestArtifactWithParent( "target/test-classes/com/example/test/test-artifact-module-a", - "target/test-repository/com/example/test/test-artifact-module-a" ); - - ProjectVersionMetadata metadata = storage.readProjectVersionMetadata( - new ReadMetadataRequest( 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() ); - - List paths = new ArrayList<>(); - paths.add( "target/test-repository/com/example/test/test-artifact-module-a" ); - paths.add( "target/test-repository/com/example/test/test-artifact-parent" ); - paths.add( "target/test-repository/com/example/test/test-artifact-root" ); - - deleteTestArtifactWithParent( paths ); - } - - @Test - public void testGetProjectVersionMetadataWithParentNotInAnyRemoteRepo() - throws Exception - { - assertNotNull( storage ); - copyTestArtifactWithParent( "target/test-classes/com/example/test/test-artifact-module-a", - "target/test-repository/com/example/test/test-artifact-module-a" ); - - ProjectVersionMetadata metadata = storage.readProjectVersionMetadata( - new ReadMetadataRequest( 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() ); - - List paths = new ArrayList<>(); - paths.add( "target/test-repository/com/example/test/test-artifact-module-a" ); - paths.add( "target/test-repository/com/example/test/test-artifact-parent" ); - paths.add( "target/test-repository/com/example/test/test-artifact-root" ); - - deleteTestArtifactWithParent( paths ); - } - - @Test - public void testGetProjectVersionMetadataWithParentSnapshotVersion() - throws Exception - { - - copyTestArtifactWithParent( "target/test-classes/com/example/test/test-snapshot-artifact-module-a", - "target/test-repository/com/example/test/test-snapshot-artifact-module-a" ); - - copyTestArtifactWithParent( "src/test/resources/com/example/test/test-artifact-parent", - "target/test-repository/com/example/test/test-artifact-parent" ); - - copyTestArtifactWithParent( "target/test-classes/com/example/test/test-snapshot-artifact-root", - "target/test-repository/com/example/test/test-snapshot-artifact-root" ); - - ProjectVersionMetadata metadata = storage.readProjectVersionMetadata( - new ReadMetadataRequest( TEST_REPO_ID, "com.example.test", "test-snapshot-artifact-module-a", - "1.1-SNAPSHOT" ) ); - - MavenProjectFacet facet = (MavenProjectFacet) metadata.getFacet( MavenProjectFacet.FACET_ID ); - assertEquals( "jar", facet.getPackaging() ); - assertEquals( "com.example.test", facet.getParent().getGroupId() ); - assertEquals( "test-snapshot-artifact-root", facet.getParent().getArtifactId() ); - assertEquals( "1.1-SNAPSHOT", facet.getParent().getVersion() ); - assertEquals( "test-snapshot-artifact-module-a", facet.getArtifactId() ); - assertEquals( "com.example.test", facet.getGroupId() ); - assertNull( metadata.getCiManagement() ); - assertNotNull( metadata.getDescription() ); - - checkApacheLicense( metadata ); - - assertEquals( "1.1-SNAPSHOT", metadata.getId() ); - assertEquals( "Test Snapshot Artifact :: Module A", metadata.getName() ); - String path = "test-snapshot-artifact/trunk/test-snapshot-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 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" ); - - List paths = new ArrayList<>(); - paths.add( "target/test-repository/com/example/test/test-snapshot-artifact-module-a" ); - paths.add( "target/test-repository/com/example/test/test-snapshot-artifact-root" ); - - deleteTestArtifactWithParent( paths ); - } - - @Test - public void testGetProjectVersionMetadataWithParentSnapshotVersionAndSnapNotAllowed() - throws Exception - { - testRepo.setSnapshots( false ); - configuration.save( c ); - repositoryRegistry.reload(); - assertFalse(repositoryRegistry.getManagedRepository(testRepo.getId()).getActiveReleaseSchemes().contains(ReleaseScheme.SNAPSHOT)); - assertFalse( c.getManagedRepositories().get( 0 ).isSnapshots() ); - copyTestArtifactWithParent( "target/test-classes/com/example/test/test-snapshot-artifact-module-a", - "target/test-repository/com/example/test/test-snapshot-artifact-module-a" ); - - try - { - ProjectVersionMetadata metadata = storage.readProjectVersionMetadata( - new ReadMetadataRequest( TEST_REPO_ID, "com.example.test", "test-snapshot-artifact-module-a", - "1.1-SNAPSHOT" ) ); - fail( "Should not be found" ); - } - catch ( RepositoryStorageRuntimeException e ) - { - } - - List paths = new ArrayList<>(); - paths.add( "target/test-repository/com/example/test/test-snapshot-artifact-module-a" ); - paths.add( "target/test-repository/com/example/test/test-snapshot-artifact-root" ); - - deleteTestArtifactWithParent( paths ); - } - // Tests for MRM-1411 - END - - private void assertDependency( Dependency dependency, String groupId, String artifactId, String version ) - { - assertDependency( dependency, groupId, artifactId, version, "compile" ); - } - - private void assertDependency( Dependency dependency, String groupId, String artifactId, String version, - String scope ) - { - assertEquals( artifactId, dependency.getArtifactId() ); - assertEquals( "jar", dependency.getType() ); - assertEquals( version, dependency.getVersion() ); - assertEquals( groupId, dependency.getNamespace() ); - assertEquals( scope, dependency.getScope() ); - assertNull( dependency.getClassifier() ); - assertNull( dependency.getSystemPath() ); - } - - private void assertArtifact( ArtifactMetadata artifact, String id, int size, String sha1, String md5 ) - { - assertEquals( id, artifact.getId() ); - assertEquals( md5, artifact.getMd5() ); - assertEquals( sha1, artifact.getSha1() ); - assertEquals( size, artifact.getSize() ); - assertEquals( "org.codehaus.plexus", artifact.getNamespace() ); - assertEquals( "plexus-spring", artifact.getProject() ); - assertEquals( "1.2", artifact.getVersion() ); - assertEquals( TEST_REPO_ID, artifact.getRepositoryId() ); - } - - private void assertMailingList( MailingList mailingList, String name, String archive, String post, String subscribe, - String unsubscribe, List otherArchives, boolean allowPost ) - { - assertEquals( archive, mailingList.getMainArchiveUrl() ); - if ( allowPost ) - { - assertEquals( post, mailingList.getPostAddress() ); - } - else - { - assertNull( mailingList.getPostAddress() ); - } - assertEquals( subscribe, mailingList.getSubscribeAddress() ); - assertEquals( unsubscribe, mailingList.getUnsubscribeAddress() ); - assertEquals( name, mailingList.getName() ); - assertEquals( otherArchives, mailingList.getOtherArchives() ); - } - - private void assertMailingList( String prefix, MailingList mailingList, String name, boolean allowPost, - String nabbleUrl ) - { - List otherArchives = new ArrayList<>(); - otherArchives.add( "http://www.mail-archive.com/" + prefix + "@archiva.apache.org" ); - if ( nabbleUrl != null ) - { - otherArchives.add( nabbleUrl ); - } - otherArchives.add( "http://markmail.org/list/org.apache.archiva." + prefix ); - assertMailingList( mailingList, name, "http://mail-archives.apache.org/mod_mbox/archiva-" + prefix + "/", - prefix + "@archiva.apache.org", prefix + "-subscribe@archiva.apache.org", - prefix + "-unsubscribe@archiva.apache.org", otherArchives, allowPost ); - } - - private void checkApacheLicense( ProjectVersionMetadata metadata ) - { - assertEquals( Arrays.asList( new License( "The Apache Software License, Version 2.0", - "http://www.apache.org/licenses/LICENSE-2.0.txt" ) ), - metadata.getLicenses() ); - } - - private void checkOrganizationApache( ProjectVersionMetadata metadata ) - { - assertEquals( "The Apache Software Foundation", metadata.getOrganization().getName() ); - assertEquals( "http://www.apache.org/", metadata.getOrganization().getUrl() ); - } - - private void deleteTestArtifactWithParent( List pathsToBeDeleted ) - throws IOException - { - for ( String path : pathsToBeDeleted ) - { - Path dir = Paths.get( org.apache.archiva.common.utils.FileUtils.getBasedir(), path ); - org.apache.archiva.common.utils.FileUtils.deleteDirectory( dir ); - - assertFalse(Files.exists( dir) ); - } - Path dest = Paths.get( org.apache.archiva.common.utils.FileUtils.getBasedir(), "target/test-repository/com/example/test/test-artifact-module-a" ); - Path parentPom = - Paths.get( org.apache.archiva.common.utils.FileUtils.getBasedir(), "target/test-repository/com/example/test/test-artifact-parent" ); - Path rootPom = Paths.get( org.apache.archiva.common.utils.FileUtils.getBasedir(), "target/test-repository/com/example/test/test-artifact-root" ); - - org.apache.archiva.common.utils.FileUtils.deleteDirectory( dest ); - org.apache.archiva.common.utils.FileUtils.deleteDirectory( parentPom ); - org.apache.archiva.common.utils.FileUtils.deleteDirectory( rootPom ); - - assertFalse( Files.exists(dest) ); - assertFalse( Files.exists(parentPom) ); - assertFalse( Files.exists(rootPom) ); - } - - private Path copyTestArtifactWithParent( String srcPath, String destPath ) - throws IOException - { - Path src = Paths.get( org.apache.archiva.common.utils.FileUtils.getBasedir(), srcPath ); - Path dest = Paths.get( org.apache.archiva.common.utils.FileUtils.getBasedir(), destPath ); - - FileUtils.copyDirectory( src.toFile(), dest.toFile() ); - assertTrue( Files.exists(dest) ); - return dest; - } - -} diff --git a/archiva-modules/archiva-maven/archiva-maven-repository/src/test/java/org/apache/archiva/repository/maven/metadata/storage/Maven2RepositoryMetadataResolverManagedReleaseTest.java b/archiva-modules/archiva-maven/archiva-maven-repository/src/test/java/org/apache/archiva/repository/maven/metadata/storage/Maven2RepositoryMetadataResolverManagedReleaseTest.java deleted file mode 100644 index 4e79a833e..000000000 --- a/archiva-modules/archiva-maven/archiva-maven-repository/src/test/java/org/apache/archiva/repository/maven/metadata/storage/Maven2RepositoryMetadataResolverManagedReleaseTest.java +++ /dev/null @@ -1,147 +0,0 @@ -package org.apache.archiva.repository.maven.metadata.storage; - -/* - * 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.filter.AllFilter; -import org.apache.archiva.filter.Filter; -import org.apache.archiva.metadata.model.ProjectVersionMetadata; -import org.apache.archiva.metadata.repository.storage.ReadMetadataRequest; -import org.apache.archiva.metadata.repository.storage.RepositoryStorageRuntimeException; -import org.apache.archiva.maven.common.proxy.WagonFactory; -import org.apache.archiva.repository.RepositoryRegistry; -import org.apache.archiva.repository.base.RepositoryHandlerDependencies; -import org.junit.Before; -import org.junit.Test; - -import javax.inject.Inject; -import javax.inject.Named; - - -public class Maven2RepositoryMetadataResolverManagedReleaseTest - extends Maven2RepositoryMetadataResolverTest -{ - private static final Filter ALL = new AllFilter(); - - @Inject - @Named ( "repositoryStorage#maven2") - private Maven2RepositoryStorage storage; - - @Inject - RepositoryRegistry repositoryRegistry; - - @SuppressWarnings( "unused" ) - @Inject - RepositoryHandlerDependencies repositoryHandlerDependencies; - - - 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"; - - private WagonFactory wagonFactory; - - @Before - @Override - public void setUp() - throws Exception - { - super.setUp(); - - testRepo.setReleases( true ); - testRepo.setSnapshots( false ); - - configuration.save( c ); - - repositoryRegistry.reload(); - - assertFalse( c.getManagedRepositories().get( 0 ).isSnapshots() ); - assertTrue( c.getManagedRepositories().get( 0 ).isReleases() ); - - } - - @Test - @Override - public void testModelWithJdkProfileActivation() - throws Exception - { - // skygo IMHO must fail because TEST_REPO_ID ( is snap ,no release) and we seek for a snapshot - - ReadMetadataRequest readMetadataRequest = - new ReadMetadataRequest().repositoryId( TEST_REPO_ID ).namespace( "org.apache.maven" ).projectId( - "maven-archiver" ).projectVersion( "2.4.1" ); - - ProjectVersionMetadata metadata = storage.readProjectVersionMetadata( readMetadataRequest ); - } - - @Test (expected = RepositoryStorageRuntimeException.class) - @Override - public void testGetProjectVersionMetadataForTimestampedSnapshotMissingMetadata() - throws Exception - { - ReadMetadataRequest readMetadataRequest = - new ReadMetadataRequest().repositoryId( TEST_REPO_ID ).namespace( "com.example.test" ).projectId( - "missing-metadata" ).projectVersion( "1.0-SNAPSHOT" ); - storage.readProjectVersionMetadata( readMetadataRequest ); - } - - @Test (expected = RepositoryStorageRuntimeException.class) - @Override - public void testGetProjectVersionMetadataForTimestampedSnapshotMalformedMetadata() - throws Exception - { - ReadMetadataRequest readMetadataRequest = - new ReadMetadataRequest().repositoryId( TEST_REPO_ID ).namespace( "com.example.test" ).projectVersion( - "malformed-metadata" ).projectVersion( "1.0-SNAPSHOT" ); - storage.readProjectVersionMetadata( readMetadataRequest ); - } - - @Test (expected = RepositoryStorageRuntimeException.class) - @Override - public void testGetProjectVersionMetadataForTimestampedSnapshot() - throws Exception - { - super.testGetProjectVersionMetadataForTimestampedSnapshot(); - } - - - @Test (expected = RepositoryStorageRuntimeException.class) - @Override - public void testGetProjectVersionMetadataForTimestampedSnapshotIncompleteMetadata() - throws Exception - { - super.testGetProjectVersionMetadataForTimestampedSnapshotIncompleteMetadata(); - } - -} diff --git a/archiva-modules/archiva-maven/archiva-maven-repository/src/test/java/org/apache/archiva/repository/maven/metadata/storage/Maven2RepositoryMetadataResolverManagedSnapshotTest.java b/archiva-modules/archiva-maven/archiva-maven-repository/src/test/java/org/apache/archiva/repository/maven/metadata/storage/Maven2RepositoryMetadataResolverManagedSnapshotTest.java deleted file mode 100644 index 09964e6c3..000000000 --- a/archiva-modules/archiva-maven/archiva-maven-repository/src/test/java/org/apache/archiva/repository/maven/metadata/storage/Maven2RepositoryMetadataResolverManagedSnapshotTest.java +++ /dev/null @@ -1,146 +0,0 @@ -package org.apache.archiva.repository.maven.metadata.storage; - -/* - * 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.filter.AllFilter; -import org.apache.archiva.filter.Filter; -import org.apache.archiva.metadata.model.ProjectVersionMetadata; -import org.apache.archiva.metadata.repository.storage.ReadMetadataRequest; -import org.apache.archiva.metadata.repository.storage.RepositoryStorageRuntimeException; -import org.apache.archiva.repository.RepositoryRegistry; -import org.apache.archiva.repository.base.RepositoryHandlerDependencies; -import org.junit.Before; -import org.junit.Test; - -import javax.inject.Inject; -import javax.inject.Named; - -public class Maven2RepositoryMetadataResolverManagedSnapshotTest - extends Maven2RepositoryMetadataResolverTest -{ - private static final Filter ALL = new AllFilter(); - - @Inject - @Named ( "repositoryStorage#maven2") - private Maven2RepositoryStorage storage; - - @Inject - RepositoryRegistry repositoryRegistry; - - @SuppressWarnings( "unused" ) - @Inject - RepositoryHandlerDependencies repositoryHandlerDependencies; - - - 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"; - - - @Before - @Override - public void setUp() - throws Exception - { - super.setUp(); - - testRepo.setReleases( false ); - testRepo.setSnapshots( true ); - - configuration.save( c ); - - repositoryRegistry.reload(); - - assertTrue( c.getManagedRepositories().get( 0 ).isSnapshots() ); - assertFalse( c.getManagedRepositories().get( 0 ).isReleases() ); - } - - @Test (expected = RepositoryStorageRuntimeException.class) - @Override - public void testModelWithJdkProfileActivation() - throws Exception - { - // skygo IMHO must fail because TEST_REPO_ID ( is snap ,no release) and we seek for a snapshot - - ReadMetadataRequest readMetadataRequest = - new ReadMetadataRequest().repositoryId( TEST_REPO_ID ).namespace( "org.apache.maven" ).projectId( - "maven-archiver" ).projectVersion( "2.4.1" ); - - ProjectVersionMetadata metadata = storage.readProjectVersionMetadata( readMetadataRequest ); - } - - @Test (expected = RepositoryStorageRuntimeException.class) - @Override - public void testGetProjectVersionMetadataForMislocatedPom() - throws Exception - { - ReadMetadataRequest readMetadataRequest = - new ReadMetadataRequest().repositoryId( TEST_REPO_ID ).namespace( "com.example.test" ).projectId( - "mislocated-pom" ).projectVersion( "1.0" ); - storage.readProjectVersionMetadata( readMetadataRequest ); - - } - - @Test - @Override - public void testGetProjectVersionMetadata() - throws Exception - { - // super test is on release - } - - @Test (expected = RepositoryStorageRuntimeException.class) - @Override - public void testGetProjectVersionMetadataForInvalidPom() - throws Exception - { - ReadMetadataRequest readMetadataRequest = - new ReadMetadataRequest().repositoryId( TEST_REPO_ID ).namespace( "com.example.test" ).projectId( - "invalid-pom" ).projectVersion( "1.0" ); - storage.readProjectVersionMetadata( readMetadataRequest ); - } - - @Test (expected = RepositoryStorageRuntimeException.class) - @Override - public void testGetProjectVersionMetadataForMissingPom() - throws Exception - { - ReadMetadataRequest readMetadataRequest = - new ReadMetadataRequest().repositoryId( TEST_REPO_ID ).namespace( "com.example.test" ).projectId( - "missing-pom" ).projectVersion( "1.0" ); - storage.readProjectVersionMetadata( readMetadataRequest ); - } -} diff --git a/archiva-modules/archiva-maven/archiva-maven-repository/src/test/java/org/apache/archiva/repository/maven/metadata/storage/Maven2RepositoryMetadataResolverTest.java b/archiva-modules/archiva-maven/archiva-maven-repository/src/test/java/org/apache/archiva/repository/maven/metadata/storage/Maven2RepositoryMetadataResolverTest.java deleted file mode 100644 index 0dc0e54fe..000000000 --- a/archiva-modules/archiva-maven/archiva-maven-repository/src/test/java/org/apache/archiva/repository/maven/metadata/storage/Maven2RepositoryMetadataResolverTest.java +++ /dev/null @@ -1,820 +0,0 @@ -package org.apache.archiva.repository.maven.metadata.storage; - -/* - * 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.configuration.ArchivaConfiguration; -import org.apache.archiva.configuration.Configuration; -import org.apache.archiva.configuration.ManagedRepositoryConfiguration; -import org.apache.archiva.configuration.ProxyConnectorConfiguration; -import org.apache.archiva.configuration.RemoteRepositoryConfiguration; -import org.apache.archiva.configuration.RepositoryScanningConfiguration; -import org.apache.archiva.filter.AllFilter; -import org.apache.archiva.filter.ExcludesFilter; -import org.apache.archiva.filter.Filter; -import org.apache.archiva.maven.metadata.model.MavenArtifactFacet; -import org.apache.archiva.metadata.model.ArtifactMetadata; -import org.apache.archiva.metadata.model.Dependency; -import org.apache.archiva.metadata.model.License; -import org.apache.archiva.metadata.model.MailingList; -import org.apache.archiva.metadata.model.ProjectVersionMetadata; -import org.apache.archiva.metadata.repository.storage.ReadMetadataRequest; -import org.apache.archiva.metadata.repository.storage.RepositoryStorageMetadataInvalidException; -import org.apache.archiva.metadata.repository.storage.RepositoryStorageMetadataNotFoundException; -import org.apache.archiva.maven.common.proxy.WagonFactory; -import org.apache.archiva.maven.common.proxy.WagonFactoryRequest; -import org.apache.archiva.repository.RepositoryRegistry; -import org.apache.archiva.repository.base.RepositoryHandlerDependencies; -import org.apache.archiva.test.utils.ArchivaSpringJUnit4ClassRunner; -import org.apache.commons.io.FileUtils; -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 javax.inject.Inject; -import javax.inject.Named; -import java.io.IOException; -import java.net.URL; -import java.nio.file.Files; -import java.nio.file.Path; -import java.nio.file.Paths; -import java.nio.file.StandardCopyOption; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collection; -import java.util.Collections; -import java.util.Comparator; -import java.util.List; - -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.when; - -@RunWith ( ArchivaSpringJUnit4ClassRunner.class ) -@ContextConfiguration ( { "classpath*:/META-INF/spring-context.xml", "classpath:/spring-context.xml" } ) -public class Maven2RepositoryMetadataResolverTest - extends TestCase -{ - private static final Filter ALL = new AllFilter(); - - @Inject - @Named ( "repositoryStorage#maven2" ) - private Maven2RepositoryStorage storage; - - @Inject - RepositoryRegistry repositoryRegistry; - - @SuppressWarnings( "unused" ) - @Inject - RepositoryHandlerDependencies repositoryHandlerDependencies; - - - 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"; - - @Inject - @Named ( "archivaConfiguration#default" ) - protected ArchivaConfiguration configuration; - - private WagonFactory wagonFactory; - - ManagedRepositoryConfiguration testRepo; - - Configuration c; - - @Before - @Override - public void setUp() - throws Exception - { - super.setUp(); - - c = new Configuration(); - - c.setVersion("2.0"); - testRepo = new ManagedRepositoryConfiguration(); - testRepo.setId( TEST_REPO_ID ); - testRepo.setLocation( Paths.get( "target/test-repository" ).toAbsolutePath().toString() ); - testRepo.setReleases( true ); - testRepo.setSnapshots( true ); - 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 ); - - RepositoryScanningConfiguration scCfg = new RepositoryScanningConfiguration(); - c.setRepositoryScanning(scCfg); - - configuration.save( c ); - assertFalse(configuration.isDefaulted()); - repositoryRegistry.reload(); - - assertTrue( c.getManagedRepositories().get( 0 ).isSnapshots() ); - assertTrue( c.getManagedRepositories().get( 0 ).isReleases() ); - - wagonFactory = mock( WagonFactory.class ); - - storage.setWagonFactory( wagonFactory ); - - Wagon wagon = new MockWagon(); - when( wagonFactory.getWagon( new WagonFactoryRequest().protocol( "wagon#http" ) ) ).thenReturn( wagon ); - } - - @Test - public void testModelWithJdkProfileActivation() - throws Exception - { - ReadMetadataRequest readMetadataRequest = - new ReadMetadataRequest().repositoryId( TEST_REPO_ID ).namespace( "org.apache.maven" ).projectId( - "maven-archiver" ).projectVersion( "2.4.1" ); - ProjectVersionMetadata metadata = storage.readProjectVersionMetadata( readMetadataRequest ); - MavenProjectFacet facet = (MavenProjectFacet) metadata.getFacet( MavenProjectFacet.FACET_ID ); - } - - @Test - public void testGetProjectVersionMetadata() - throws Exception - { - ProjectVersionMetadata metadata = storage.readProjectVersionMetadata( - new ReadMetadataRequest( TEST_REPO_ID, "org.apache.archiva", "archiva-common", "1.2.1" ) ); - MavenProjectFacet facet = (MavenProjectFacet) metadata.getFacet( MavenProjectFacet.FACET_ID ); - assertEquals( "jar", facet.getPackaging() ); - assertEquals( "http://archiva.apache.org/ref/1.2.1/archiva-base/archiva-common", metadata.getUrl() ); - assertEquals( "org.apache.archiva", facet.getParent().getGroupId() ); - assertEquals( "archiva-base", facet.getParent().getArtifactId() ); - assertEquals( "1.2.1", facet.getParent().getVersion() ); - assertEquals( "archiva-common", facet.getArtifactId() ); - assertEquals( "org.apache.archiva", facet.getGroupId() ); - assertEquals( "continuum", metadata.getCiManagement().getSystem() ); - assertEquals( "http://vmbuild.apache.org/continuum", metadata.getCiManagement().getUrl() ); - assertNotNull( metadata.getDescription() ); - // TODO: this would be better -// assertEquals( -// "Archiva is an application for managing one or more remote repositories, including administration, artifact handling, browsing and searching.", -// metadata.getDescription() ); - assertEquals( "1.2.1", metadata.getId() ); - assertEquals( "jira", metadata.getIssueManagement().getSystem() ); - assertEquals( "http://jira.codehaus.org/browse/MRM", metadata.getIssueManagement().getUrl() ); - checkApacheLicense( metadata ); - assertEquals( "Archiva Base :: Common", metadata.getName() ); - String path = "archiva/tags/archiva-1.2.1/archiva-modules/archiva-base/archiva-common"; - assertEquals( ASF_SCM_CONN_BASE + path, metadata.getScm().getConnection() ); - assertEquals( ASF_SCM_DEV_CONN_BASE + path, metadata.getScm().getDeveloperConnection() ); - assertEquals( ASF_SCM_VIEWVC_BASE + path, metadata.getScm().getUrl() ); - checkOrganizationApache( metadata ); - - assertEquals( 4, metadata.getMailingLists().size() ); - assertMailingList( "users", metadata.getMailingLists().get( 0 ), "Archiva User List", true, - "http://www.nabble.com/archiva-users-f16426.html" ); - assertMailingList( "dev", metadata.getMailingLists().get( 1 ), "Archiva Developer List", true, - "http://www.nabble.com/archiva-dev-f16427.html" ); - assertMailingList( "commits", metadata.getMailingLists().get( 2 ), "Archiva Commits List", false, null ); - assertMailingList( "issues", metadata.getMailingLists().get( 3 ), "Archiva Issues List", false, - "http://www.nabble.com/Archiva---Issues-f29617.html" ); - - List dependencies = metadata.getDependencies(); - assertEquals( 10, dependencies.size() ); - assertDependency( dependencies.get( 0 ), "commons-lang", "commons-lang", "2.2" ); - assertDependency( dependencies.get( 1 ), "commons-io", "commons-io", "1.4" ); - assertDependency( dependencies.get( 2 ), "org.slf4j", "slf4j-api", "1.5.0" ); - assertDependency( dependencies.get( 3 ), "org.codehaus.plexus", "plexus-component-api", "1.0-alpha-22" ); - assertDependency( dependencies.get( 4 ), "org.codehaus.plexus", "plexus-spring", "1.2", "test" ); - assertDependency( dependencies.get( 5 ), "xalan", "xalan", "2.7.0" ); - assertDependency( dependencies.get( 6 ), "dom4j", "dom4j", "1.6.1", "test" ); - assertDependency( dependencies.get( 7 ), "junit", "junit", "3.8.1", "test" ); - assertDependency( dependencies.get( 8 ), "easymock", "easymock", "1.2_Java1.3", "test" ); - assertDependency( dependencies.get( 9 ), "easymock", "easymockclassextension", "1.2", "test" ); - - assertEquals( 8, metadata.getProperties().size() ); - assertEquals( "http://www.apache.org/images/asf_logo_wide.gif", metadata.getProperties().get("organization.logo") ); - } - - @Test - public void testGetArtifactMetadata() - throws Exception - { - Collection springArtifacts = storage.readArtifactsMetadata( - new ReadMetadataRequest( TEST_REPO_ID, "org.codehaus.plexus", "plexus-spring", "1.2", ALL ) ); - List artifacts = new ArrayList<>( springArtifacts ); - Collections.sort( artifacts, new Comparator() - { - @Override - public int compare( ArtifactMetadata o1, ArtifactMetadata o2 ) - { - return o1.getId().compareTo( o2.getId() ); - } - } ); - - assertEquals( 3, artifacts.size() ); - - ArtifactMetadata artifactMetadata = artifacts.get( 0 ); - assertEquals( "plexus-spring-1.2-sources.jar", artifactMetadata.getId() ); - MavenArtifactFacet facet = (MavenArtifactFacet) artifactMetadata.getFacet( MavenArtifactFacet.FACET_ID ); - assertEquals( 0, facet.getBuildNumber() ); - assertNull( facet.getTimestamp() ); - assertEquals( "sources", facet.getClassifier() ); - assertEquals( "java-source", facet.getType() ); - - artifactMetadata = artifacts.get( 1 ); - assertEquals( "plexus-spring-1.2.jar", artifactMetadata.getId() ); - facet = (MavenArtifactFacet) artifactMetadata.getFacet( MavenArtifactFacet.FACET_ID ); - assertEquals( 0, facet.getBuildNumber() ); - assertNull( facet.getTimestamp() ); - assertNull( facet.getClassifier() ); - assertEquals( "jar", facet.getType() ); - - artifactMetadata = artifacts.get( 2 ); - assertEquals( "plexus-spring-1.2.pom", artifactMetadata.getId() ); - facet = (MavenArtifactFacet) artifactMetadata.getFacet( MavenArtifactFacet.FACET_ID ); - assertEquals( 0, facet.getBuildNumber() ); - assertNull( facet.getTimestamp() ); - assertNull( facet.getClassifier() ); - assertEquals( "pom", facet.getType() ); - } - - @Test - public void testGetArtifactMetadataSnapshots() - throws Exception - { - Collection testArtifacts = storage.readArtifactsMetadata( - new ReadMetadataRequest( TEST_REPO_ID, "com.example.test", "test-artifact", "1.0-SNAPSHOT", ALL ) ); - List artifacts = new ArrayList<>( testArtifacts ); - Collections.sort( artifacts, new Comparator() - { - @Override - public int compare( ArtifactMetadata o1, ArtifactMetadata o2 ) - { - return o1.getId().compareTo( o2.getId() ); - } - } ); - - assertEquals( 6, artifacts.size() ); - - ArtifactMetadata artifactMetadata = artifacts.get( 0 ); - assertEquals( "test-artifact-1.0-20100308.230825-1.jar", artifactMetadata.getId() ); - MavenArtifactFacet facet = (MavenArtifactFacet) artifactMetadata.getFacet( MavenArtifactFacet.FACET_ID ); - assertEquals( 1, facet.getBuildNumber() ); - assertEquals( "20100308.230825", facet.getTimestamp() ); - assertNull( facet.getClassifier() ); - assertEquals( "jar", facet.getType() ); - - artifactMetadata = artifacts.get( 1 ); - assertEquals( "test-artifact-1.0-20100308.230825-1.pom", artifactMetadata.getId() ); - facet = (MavenArtifactFacet) artifactMetadata.getFacet( MavenArtifactFacet.FACET_ID ); - assertEquals( 1, facet.getBuildNumber() ); - assertEquals( "20100308.230825", facet.getTimestamp() ); - assertNull( facet.getClassifier() ); - assertEquals( "pom", facet.getType() ); - - artifactMetadata = artifacts.get( 2 ); - assertEquals( "test-artifact-1.0-20100310.014828-2-javadoc.jar", artifactMetadata.getId() ); - facet = (MavenArtifactFacet) artifactMetadata.getFacet( MavenArtifactFacet.FACET_ID ); - assertEquals( 2, facet.getBuildNumber() ); - assertEquals( "20100310.014828", facet.getTimestamp() ); - assertEquals( "javadoc", facet.getClassifier() ); - assertEquals( "javadoc", facet.getType() ); - - artifactMetadata = artifacts.get( 3 ); - assertEquals( "test-artifact-1.0-20100310.014828-2-sources.jar", artifactMetadata.getId() ); - facet = (MavenArtifactFacet) artifactMetadata.getFacet( MavenArtifactFacet.FACET_ID ); - assertEquals( 2, facet.getBuildNumber() ); - assertEquals( "20100310.014828", facet.getTimestamp() ); - assertEquals( "sources", facet.getClassifier() ); - assertEquals( "java-source", facet.getType() ); - - artifactMetadata = artifacts.get( 4 ); - assertEquals( "test-artifact-1.0-20100310.014828-2.jar", artifactMetadata.getId() ); - facet = (MavenArtifactFacet) artifactMetadata.getFacet( MavenArtifactFacet.FACET_ID ); - assertEquals( 2, facet.getBuildNumber() ); - assertEquals( "20100310.014828", facet.getTimestamp() ); - assertNull( facet.getClassifier() ); - assertEquals( "jar", facet.getType() ); - - artifactMetadata = artifacts.get( 5 ); - assertEquals( "test-artifact-1.0-20100310.014828-2.pom", artifactMetadata.getId() ); - facet = (MavenArtifactFacet) artifactMetadata.getFacet( MavenArtifactFacet.FACET_ID ); - assertEquals( 2, facet.getBuildNumber() ); - assertEquals( "20100310.014828", facet.getTimestamp() ); - assertNull( facet.getClassifier() ); - assertEquals( "pom", facet.getType() ); - } - - @Test - public void testGetArtifactMetadataSnapshotsMRM1859() - throws Exception - { - Path repoDir = Paths.get("target/test-repository/com/example/test/test-artifact/1.0-SNAPSHOT"); - URL url = Thread.currentThread().getContextClassLoader().getResource("resolver-status.properties"); - Path resFile = Paths.get(url.toURI()); - Path destFile = repoDir.resolve(resFile.getFileName()); - Files.copy(resFile, destFile, StandardCopyOption.REPLACE_EXISTING); - URL url2 = Thread.currentThread().getContextClassLoader().getResource("test01.properties"); - Path resFile2 = Paths.get(url2.toURI()); - Path destFile2 = repoDir.resolve(resFile2.getFileName()); - Files.copy(resFile2, destFile2, StandardCopyOption.REPLACE_EXISTING); - - try { - - - Collection testArtifacts = storage.readArtifactsMetadata( - new ReadMetadataRequest(TEST_REPO_ID, "com.example.test", "test-artifact", "1.0-SNAPSHOT", ALL)); - List artifacts = new ArrayList<>(testArtifacts); - Collections.sort(artifacts, new Comparator() { - @Override - public int compare(ArtifactMetadata o1, ArtifactMetadata o2) { - return o1.getId().compareTo(o2.getId()); - } - }); - - assertEquals(6, artifacts.size()); - - ArtifactMetadata artifactMetadata = artifacts.get(0); - assertEquals("test-artifact-1.0-20100308.230825-1.jar", artifactMetadata.getId()); - MavenArtifactFacet facet = (MavenArtifactFacet) artifactMetadata.getFacet(MavenArtifactFacet.FACET_ID); - assertEquals(1, facet.getBuildNumber()); - assertEquals("20100308.230825", facet.getTimestamp()); - assertNull(facet.getClassifier()); - assertEquals("jar", facet.getType()); - - artifactMetadata = artifacts.get(1); - assertEquals("test-artifact-1.0-20100308.230825-1.pom", artifactMetadata.getId()); - facet = (MavenArtifactFacet) artifactMetadata.getFacet(MavenArtifactFacet.FACET_ID); - assertEquals(1, facet.getBuildNumber()); - assertEquals("20100308.230825", facet.getTimestamp()); - assertNull(facet.getClassifier()); - assertEquals("pom", facet.getType()); - - artifactMetadata = artifacts.get(2); - assertEquals("test-artifact-1.0-20100310.014828-2-javadoc.jar", artifactMetadata.getId()); - facet = (MavenArtifactFacet) artifactMetadata.getFacet(MavenArtifactFacet.FACET_ID); - assertEquals(2, facet.getBuildNumber()); - assertEquals("20100310.014828", facet.getTimestamp()); - assertEquals("javadoc", facet.getClassifier()); - assertEquals("javadoc", facet.getType()); - - artifactMetadata = artifacts.get(3); - assertEquals("test-artifact-1.0-20100310.014828-2-sources.jar", artifactMetadata.getId()); - facet = (MavenArtifactFacet) artifactMetadata.getFacet(MavenArtifactFacet.FACET_ID); - assertEquals(2, facet.getBuildNumber()); - assertEquals("20100310.014828", facet.getTimestamp()); - assertEquals("sources", facet.getClassifier()); - assertEquals("java-source", facet.getType()); - - artifactMetadata = artifacts.get(4); - assertEquals("test-artifact-1.0-20100310.014828-2.jar", artifactMetadata.getId()); - facet = (MavenArtifactFacet) artifactMetadata.getFacet(MavenArtifactFacet.FACET_ID); - assertEquals(2, facet.getBuildNumber()); - assertEquals("20100310.014828", facet.getTimestamp()); - assertNull(facet.getClassifier()); - assertEquals("jar", facet.getType()); - - artifactMetadata = artifacts.get(5); - assertEquals("test-artifact-1.0-20100310.014828-2.pom", artifactMetadata.getId()); - facet = (MavenArtifactFacet) artifactMetadata.getFacet(MavenArtifactFacet.FACET_ID); - assertEquals(2, facet.getBuildNumber()); - assertEquals("20100310.014828", facet.getTimestamp()); - assertNull(facet.getClassifier()); - assertEquals("pom", facet.getType()); - - } finally { - Files.delete(destFile); - Files.delete(destFile2); - } - - } - - private void assertDependency( Dependency dependency, String groupId, String artifactId, String version ) - { - assertDependency( dependency, groupId, artifactId, version, "compile" ); - } - - private void assertDependency( Dependency dependency, String groupId, String artifactId, String version, - String scope ) - { - assertEquals( artifactId, dependency.getArtifactId() ); - assertEquals( "jar", dependency.getType() ); - assertEquals( version, dependency.getVersion() ); - assertEquals( groupId, dependency.getNamespace() ); - assertEquals( scope, dependency.getScope() ); - assertNull( dependency.getClassifier() ); - assertNull( dependency.getSystemPath() ); - } - - @Test - public void testGetProjectVersionMetadataForTimestampedSnapshot() - throws Exception - { - ProjectVersionMetadata metadata = storage.readProjectVersionMetadata( - new ReadMetadataRequest( TEST_REPO_ID, "org.apache", "apache", "5-SNAPSHOT" ) ); - MavenProjectFacet facet = MavenProjectFacet.class.cast( metadata.getFacet( MavenProjectFacet.FACET_ID ) ); - assertEquals( "pom", facet.getPackaging() ); - assertEquals( "http://www.apache.org/", metadata.getUrl() ); - assertNull( facet.getParent() ); - assertEquals( "org.apache", facet.getGroupId() ); - assertEquals( "apache", facet.getArtifactId() ); - assertNull( metadata.getCiManagement() ); - assertNotNull( metadata.getDescription() ); - // TODO: this would be better -// assertEquals( -// "The Apache Software Foundation provides support for the Apache community of open-source software projects. " + -// "The Apache projects are characterized by a collaborative, consensus based development process, an open " + -// "and pragmatic software license, and a desire to create high quality software that leads the way in its " + -// "field. We consider ourselves not simply a group of projects sharing a server, but rather a community of " + -// "developers and users.", metadata.getDescription() ); - assertEquals( "5-SNAPSHOT", metadata.getId() ); - assertNull( metadata.getIssueManagement() ); - checkApacheLicense( metadata ); - assertEquals( "The Apache Software Foundation", metadata.getName() ); - String path = "maven/pom/trunk/asf"; - assertEquals( ASF_SCM_CONN_BASE + path, metadata.getScm().getConnection() ); - assertEquals( ASF_SCM_DEV_CONN_BASE + path, metadata.getScm().getDeveloperConnection() ); - assertEquals( ASF_SCM_VIEWVC_BASE + path, metadata.getScm().getUrl() ); - checkOrganizationApache( metadata ); - assertEquals( 1, metadata.getMailingLists().size() ); - assertMailingList( metadata.getMailingLists().get( 0 ), "Apache Announce List", - "http://mail-archives.apache.org/mod_mbox/www-announce/", "announce@apache.org", - "announce-subscribe@apache.org", "announce-unsubscribe@apache.org", - Collections.emptyList(), true ); - assertEquals( Collections.emptyList(), metadata.getDependencies() ); - } - - @Test - public void testGetProjectVersionMetadataForTimestampedSnapshotMissingMetadata() - throws Exception - { - try - { - storage.readProjectVersionMetadata( - new ReadMetadataRequest( TEST_REPO_ID, "com.example.test", "missing-metadata", "1.0-SNAPSHOT" ) ); - fail( "Should not be found" ); - } - catch ( RepositoryStorageMetadataNotFoundException e ) - { - assertEquals( "missing-pom", e.getId() ); - } - } - - @Test - public void testGetProjectVersionMetadataForTimestampedSnapshotMalformedMetadata() - throws Exception - { - try - { - storage.readProjectVersionMetadata( - new ReadMetadataRequest( TEST_REPO_ID, "com.example.test", "malformed-metadata", "1.0-SNAPSHOT" ) ); - fail( "Should not be found" ); - } - catch ( RepositoryStorageMetadataNotFoundException e ) - { - assertEquals( "missing-pom", e.getId() ); - } - } - - @Test - public void testGetProjectVersionMetadataForTimestampedSnapshotIncompleteMetadata() - throws Exception - { - try - { - storage.readProjectVersionMetadata( - new ReadMetadataRequest( TEST_REPO_ID, "com.example.test", "incomplete-metadata", "1.0-SNAPSHOT" ) ); - fail( "Should not be found" ); - } - catch ( RepositoryStorageMetadataNotFoundException e ) - { - assertEquals( "missing-pom", e.getId() ); - } - } - - @Test - public void testGetProjectVersionMetadataForInvalidPom() - throws Exception - { - try - { - storage.readProjectVersionMetadata( - new ReadMetadataRequest( TEST_REPO_ID, "com.example.test", "invalid-pom", "1.0" ) ); - fail( "Should have received an exception due to invalid POM" ); - } - catch ( RepositoryStorageMetadataInvalidException e ) - { - assertEquals( "invalid-pom", e.getId() ); - } - } - - @Test - public void testGetProjectVersionMetadataForMislocatedPom() - throws Exception - { - try - { - storage.readProjectVersionMetadata( - new ReadMetadataRequest( TEST_REPO_ID, "com.example.test", "mislocated-pom", "1.0" ) ); - fail( "Should have received an exception due to mislocated POM" ); - } - catch ( RepositoryStorageMetadataInvalidException e ) - { - assertEquals( "mislocated-pom", e.getId() ); - } - } - - @Test - public void testGetProjectVersionMetadataForMissingPom() - throws Exception - { - try - { - storage.readProjectVersionMetadata( - new ReadMetadataRequest( TEST_REPO_ID, "com.example.test", "missing-pom", "1.0" ) ); - fail( "Should not be found" ); - } - catch ( RepositoryStorageMetadataNotFoundException e ) - { - assertEquals( "missing-pom", e.getId() ); - } - } - - @Test - public void testGetRootNamespaces() - throws Exception - { - assertEquals( Arrays.asList( "com", "org"), storage.listRootNamespaces( TEST_REPO_ID, ALL ) ); - } - - @Test - public void testGetNamespaces() - throws Exception - { - assertEquals( Arrays.asList( "example" ), storage.listNamespaces( TEST_REPO_ID, "com", ALL ) ); - assertEquals( Arrays.asList( "test" ), storage.listNamespaces( TEST_REPO_ID, "com.example", ALL ) ); - assertEquals( Collections.emptyList(), - storage.listNamespaces( TEST_REPO_ID, "com.example.test", ALL ) ); - - assertEquals( Arrays.asList( "apache", "codehaus" ), storage.listNamespaces( TEST_REPO_ID, "org", ALL ) ); - assertEquals( Arrays.asList( "archiva", "maven" ), storage.listNamespaces( TEST_REPO_ID, "org.apache", ALL ) ); - assertEquals( Collections.emptyList(), - storage.listNamespaces( TEST_REPO_ID, "org.apache.archiva", ALL ) ); - assertEquals( Arrays.asList( "plugins", "shared" ), - storage.listNamespaces( TEST_REPO_ID, "org.apache.maven", ALL ) ); - assertEquals( Collections.emptyList(), - storage.listNamespaces( TEST_REPO_ID, "org.apache.maven.plugins", ALL ) ); - assertEquals( Collections.emptyList(), - storage.listNamespaces( TEST_REPO_ID, "org.apache.maven.shared", ALL ) ); - - assertEquals( Arrays.asList( "plexus" ), storage.listNamespaces( TEST_REPO_ID, "org.codehaus", ALL ) ); - assertEquals( Collections.emptyList(), - storage.listNamespaces( TEST_REPO_ID, "org.codehaus.plexus", ALL ) ); - } - - @Test - public void testGetProjects() - throws Exception - { - assertEquals( Collections.emptyList(), storage.listProjects( TEST_REPO_ID, "com", ALL ) ); - assertEquals( Collections.emptyList(), storage.listProjects( TEST_REPO_ID, "com.example", ALL ) ); - assertEquals( Arrays.asList( "incomplete-metadata", "invalid-pom", "malformed-metadata", "mislocated-pom", - "missing-metadata", "missing-parent", "test-artifact" ), - storage.listProjects( TEST_REPO_ID, "com.example.test", ALL ) ); - - assertEquals( Collections.emptyList(), storage.listProjects( TEST_REPO_ID, "org", ALL ) ); - assertEquals( Arrays.asList( "apache" ), storage.listProjects( TEST_REPO_ID, "org.apache", ALL ) ); - assertEquals( Arrays.asList( "archiva", "archiva-base", "archiva-common", "archiva-modules", "archiva-parent" ), - storage.listProjects( TEST_REPO_ID, "org.apache.archiva", ALL ) ); - assertEquals( Arrays.asList( "maven-archiver", "maven-parent" ), - storage.listProjects( TEST_REPO_ID, "org.apache.maven", ALL ) ); - assertEquals( Collections.emptyList(), - storage.listProjects( TEST_REPO_ID, "org.apache.maven.plugins", ALL ) ); - assertEquals( Arrays.asList( "maven-downloader", "maven-shared-components" ), - storage.listProjects( TEST_REPO_ID, "org.apache.maven.shared", ALL ) ); - } - - @Test - public void testGetProjectVersions() - throws Exception - { - assertEquals( Arrays.asList( "1.0-SNAPSHOT" ), - storage.listProjectVersions( TEST_REPO_ID, "com.example.test", "incomplete-metadata", ALL ) ); - assertEquals( Arrays.asList( "1.0-SNAPSHOT" ), - storage.listProjectVersions( TEST_REPO_ID, "com.example.test", "malformed-metadata", ALL ) ); - assertEquals( Arrays.asList( "1.0-SNAPSHOT" ), - storage.listProjectVersions( TEST_REPO_ID, "com.example.test", "missing-metadata", ALL ) ); - assertEquals( Arrays.asList( "1.0" ), - storage.listProjectVersions( TEST_REPO_ID, "com.example.test", "invalid-pom", ALL ) ); - - assertEquals( Arrays.asList( "4", "5-SNAPSHOT", "7" ), - storage.listProjectVersions( TEST_REPO_ID, "org.apache", "apache", ALL ) ); - - assertEquals( Arrays.asList( "1.2.1", "1.2.2" ), - storage.listProjectVersions( TEST_REPO_ID, "org.apache.archiva", "archiva", ALL ) ); - assertEquals( Arrays.asList( "1.2.1" ), - storage.listProjectVersions( TEST_REPO_ID, "org.apache.archiva", "archiva-base", ALL ) ); - assertEquals( Arrays.asList( "1.2.1" ), - storage.listProjectVersions( TEST_REPO_ID, "org.apache.archiva", "archiva-common", ALL ) ); - assertEquals( Arrays.asList( "1.2.1" ), - storage.listProjectVersions( TEST_REPO_ID, "org.apache.archiva", "archiva-modules", ALL ) ); - assertEquals( Arrays.asList( "3" ), - storage.listProjectVersions( TEST_REPO_ID, "org.apache.archiva", "archiva-parent", ALL ) ); - - assertEquals( Collections.emptyList(), - storage.listProjectVersions( TEST_REPO_ID, "org.apache.maven.shared", "maven-downloader", ALL ) ); - } - - @Test - public void testGetArtifacts() - throws Exception - { - List artifacts = new ArrayList<>( storage.readArtifactsMetadata( - new ReadMetadataRequest( TEST_REPO_ID, "org.codehaus.plexus", "plexus-spring", "1.2", ALL ) ) ); - assertEquals( 3, artifacts.size() ); - Collections.sort( artifacts, new Comparator() - { - @Override - public int compare( ArtifactMetadata o1, ArtifactMetadata o2 ) - { - return o1.getId().compareTo( o2.getId() ); - } - } ); - - assertArtifact( artifacts.get( 0 ), "plexus-spring-1.2-sources.jar", 0, EMPTY_SHA1, EMPTY_MD5 ); - assertArtifact( artifacts.get( 1 ), "plexus-spring-1.2.jar", 0, EMPTY_SHA1, EMPTY_MD5 ); - assertArtifact( artifacts.get( 2 ), "plexus-spring-1.2.pom", 7407, "96b14cf880e384b2d15e8193c57b65c5420ca4c5", - "f83aa25f016212a551a4b2249985effc" ); - } - - @Test - public void testGetArtifactsFiltered() - throws Exception - { - ExcludesFilter filter = - new ExcludesFilter( Collections.singletonList( "plexus-spring-1.2.pom" ) ); - List artifacts = new ArrayList<>( storage.readArtifactsMetadata( - new ReadMetadataRequest( TEST_REPO_ID, "org.codehaus.plexus", "plexus-spring", "1.2", filter ) ) ); - assertEquals( 2, artifacts.size() ); - Collections.sort( artifacts, new Comparator() - { - @Override - public int compare( ArtifactMetadata o1, ArtifactMetadata o2 ) - { - return o1.getId().compareTo( o2.getId() ); - } - } ); - - assertArtifact( artifacts.get( 0 ), "plexus-spring-1.2-sources.jar", 0, EMPTY_SHA1, EMPTY_MD5 ); - assertArtifact( artifacts.get( 1 ), "plexus-spring-1.2.jar", 0, EMPTY_SHA1, EMPTY_MD5 ); - } - - @Test - public void testGetArtifactsTimestampedSnapshots() - throws Exception - { - List artifacts = new ArrayList( storage.readArtifactsMetadata( - new ReadMetadataRequest( TEST_REPO_ID, "com.example.test", "missing-metadata", "1.0-SNAPSHOT", ALL ) ) ); - assertEquals( 1, artifacts.size() ); - - ArtifactMetadata artifact = artifacts.get( 0 ); - assertEquals( "missing-metadata-1.0-20091101.112233-1.pom", artifact.getId() ); - assertEquals( "com.example.test", artifact.getNamespace() ); - assertEquals( "missing-metadata", artifact.getProject() ); - assertEquals( "1.0-20091101.112233-1", artifact.getVersion() ); - assertEquals( TEST_REPO_ID, artifact.getRepositoryId() ); - } - - private void assertArtifact( ArtifactMetadata artifact, String id, int size, String sha1, String md5 ) - { - assertEquals( id, artifact.getId() ); - assertEquals( md5, artifact.getMd5() ); - assertEquals( sha1, artifact.getSha1() ); - assertEquals( size, artifact.getSize() ); - assertEquals( "org.codehaus.plexus", artifact.getNamespace() ); - assertEquals( "plexus-spring", artifact.getProject() ); - assertEquals( "1.2", artifact.getVersion() ); - assertEquals( TEST_REPO_ID, artifact.getRepositoryId() ); - } - - private void assertMailingList( MailingList mailingList, String name, String archive, String post, String subscribe, - String unsubscribe, List otherArchives, boolean allowPost ) - { - assertEquals( archive, mailingList.getMainArchiveUrl() ); - if ( allowPost ) - { - assertEquals( post, mailingList.getPostAddress() ); - } - else - { - assertNull( mailingList.getPostAddress() ); - } - assertEquals( subscribe, mailingList.getSubscribeAddress() ); - assertEquals( unsubscribe, mailingList.getUnsubscribeAddress() ); - assertEquals( name, mailingList.getName() ); - assertEquals( otherArchives, mailingList.getOtherArchives() ); - } - - private void assertMailingList( String prefix, MailingList mailingList, String name, boolean allowPost, - String nabbleUrl ) - { - List otherArchives = new ArrayList<>(); - otherArchives.add( "http://www.mail-archive.com/" + prefix + "@archiva.apache.org" ); - if ( nabbleUrl != null ) - { - otherArchives.add( nabbleUrl ); - } - otherArchives.add( "http://markmail.org/list/org.apache.archiva." + prefix ); - assertMailingList( mailingList, name, "http://mail-archives.apache.org/mod_mbox/archiva-" + prefix + "/", - prefix + "@archiva.apache.org", prefix + "-subscribe@archiva.apache.org", - prefix + "-unsubscribe@archiva.apache.org", otherArchives, allowPost ); - } - - private void checkApacheLicense( ProjectVersionMetadata metadata ) - { - assertEquals( Arrays.asList( new License( "The Apache Software License, Version 2.0", - "http://www.apache.org/licenses/LICENSE-2.0.txt" ) ), - metadata.getLicenses() ); - } - - private void checkOrganizationApache( ProjectVersionMetadata metadata ) - { - assertEquals( "The Apache Software Foundation", metadata.getOrganization().getName() ); - assertEquals( "http://www.apache.org/", metadata.getOrganization().getUrl() ); - } - - private void deleteTestArtifactWithParent( List pathsToBeDeleted ) - throws IOException - { - for ( String path : pathsToBeDeleted ) - { - Path dir = Paths.get( org.apache.archiva.common.utils.FileUtils.getBasedir(), path ); - org.apache.archiva.common.utils.FileUtils.deleteDirectory( dir ); - - assertFalse( Files.exists(dir) ); - } - Path dest = Paths.get( org.apache.archiva.common.utils.FileUtils.getBasedir(), "target/test-repository/com/example/test/test-artifact-module-a" ); - Path parentPom = - Paths.get( org.apache.archiva.common.utils.FileUtils.getBasedir(), "target/test-repository/com/example/test/test-artifact-parent" ); - Path rootPom = Paths.get( org.apache.archiva.common.utils.FileUtils.getBasedir(), "target/test-repository/com/example/test/test-artifact-root" ); - - org.apache.archiva.common.utils.FileUtils.deleteDirectory( dest ); - org.apache.archiva.common.utils.FileUtils.deleteDirectory( parentPom ); - org.apache.archiva.common.utils.FileUtils.deleteDirectory( rootPom ); - - assertFalse( Files.exists(dest) ); - assertFalse( Files.exists(parentPom) ); - assertFalse( Files.exists(rootPom) ); - } - - private Path copyTestArtifactWithParent( String srcPath, String destPath ) - throws IOException - { - Path src = Paths.get( org.apache.archiva.common.utils.FileUtils.getBasedir(), srcPath ); - Path dest = Paths.get( org.apache.archiva.common.utils.FileUtils.getBasedir(), destPath ); - - FileUtils.copyDirectory( src.toFile(), dest.toFile() ); - assertTrue( Files.exists(dest) ); - return dest; - } - -} diff --git a/archiva-modules/archiva-maven/archiva-maven-repository/src/test/java/org/apache/archiva/repository/maven/metadata/storage/MavenRepositoryMetadataReaderTest.java b/archiva-modules/archiva-maven/archiva-maven-repository/src/test/java/org/apache/archiva/repository/maven/metadata/storage/MavenRepositoryMetadataReaderTest.java deleted file mode 100644 index fd0b92f36..000000000 --- a/archiva-modules/archiva-maven/archiva-maven-repository/src/test/java/org/apache/archiva/repository/maven/metadata/storage/MavenRepositoryMetadataReaderTest.java +++ /dev/null @@ -1,130 +0,0 @@ -package org.apache.archiva.repository.maven.metadata.storage; - -/* - * 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.maven.metadata.MavenMetadataReader; -import org.apache.archiva.model.ArchivaRepositoryMetadata; -import org.apache.archiva.model.Plugin; -import org.apache.archiva.repository.metadata.RepositoryMetadataException; -import org.apache.archiva.test.utils.ArchivaBlockJUnit4ClassRunner; -import org.junit.Before; -import org.junit.Test; -import org.junit.runner.RunWith; - -import java.nio.file.Path; -import java.nio.file.Paths; -import java.util.Arrays; - -/** - * RepositoryMetadataReaderTest - * - * - */ -@RunWith( ArchivaBlockJUnit4ClassRunner.class ) -public class MavenRepositoryMetadataReaderTest - extends TestCase -{ - private Path defaultRepoDir; - - @Test - public void testGroupMetadata() - throws RepositoryMetadataException - { - Path metadataFile = defaultRepoDir.resolve( "org/apache/maven/plugins/maven-metadata.xml" ); - - MavenMetadataReader metadataReader = new MavenMetadataReader( ); - ArchivaRepositoryMetadata metadata = metadataReader.read( metadataFile ); - - assertNotNull( metadata ); - assertEquals( "org.apache.maven.plugins", metadata.getGroupId() ); - assertNull( metadata.getArtifactId() ); - assertNull( metadata.getReleasedVersion() ); - assertNull( metadata.getLatestVersion() ); - assertTrue( metadata.getAvailableVersions().isEmpty() ); - assertNull( metadata.getSnapshotVersion() ); - assertNull( metadata.getLastUpdated() ); - - Plugin cleanPlugin = new Plugin(); - cleanPlugin.setPrefix( "clean" ); - cleanPlugin.setArtifactId( "maven-clean-plugin" ); - cleanPlugin.setName( "Maven Clean Plugin" ); - - Plugin compilerPlugin = new Plugin(); - compilerPlugin.setPrefix( "compiler" ); - compilerPlugin.setArtifactId( "maven-compiler-plugin" ); - compilerPlugin.setName( "Maven Compiler Plugin" ); - - Plugin surefirePlugin = new Plugin(); - surefirePlugin.setPrefix( "surefire" ); - surefirePlugin.setArtifactId( "maven-surefire-plugin" ); - surefirePlugin.setName( "Maven Surefire Plugin" ); - - assertEquals( Arrays.asList( cleanPlugin, compilerPlugin, surefirePlugin ), metadata.getPlugins() ); - } - - @Test - public void testProjectMetadata() - throws RepositoryMetadataException - { - Path metadataFile = defaultRepoDir.resolve( "org/apache/maven/shared/maven-downloader/maven-metadata.xml" ); - - MavenMetadataReader metadataReader = new MavenMetadataReader( ); - ArchivaRepositoryMetadata metadata = metadataReader.read( metadataFile ); - - assertNotNull( metadata ); - assertEquals( "org.apache.maven.shared", metadata.getGroupId() ); - assertEquals( "maven-downloader", metadata.getArtifactId() ); - assertEquals( "1.1", metadata.getReleasedVersion() ); - assertNull( metadata.getLatestVersion() ); - assertEquals( Arrays.asList( "1.0", "1.1" ), metadata.getAvailableVersions() ); - assertNull( metadata.getSnapshotVersion() ); - assertEquals( "20061212214311", metadata.getLastUpdated() ); - } - - @Test - public void testProjectVersionMetadata() - throws RepositoryMetadataException - { - Path metadataFile = defaultRepoDir.resolve( "org/apache/apache/5-SNAPSHOT/maven-metadata.xml" ); - - MavenMetadataReader metadataReader = new MavenMetadataReader( ); - ArchivaRepositoryMetadata metadata = metadataReader.read(metadataFile ); - - assertNotNull( metadata ); - assertEquals( "org.apache", metadata.getGroupId() ); - assertEquals( "apache", metadata.getArtifactId() ); - assertNull( metadata.getReleasedVersion() ); - assertNull( metadata.getLatestVersion() ); - assertTrue( metadata.getAvailableVersions().isEmpty() ); - assertNotNull( metadata.getSnapshotVersion() ); - assertEquals( "20080801.151215", metadata.getSnapshotVersion().getTimestamp() ); - assertEquals( 1, metadata.getSnapshotVersion().getBuildNumber() ); - assertEquals( "20080801151215", metadata.getLastUpdated() ); - } - - @Before - @Override - public void setUp() - throws Exception - { - super.setUp(); - defaultRepoDir = Paths.get("target/test-repository"); - } -} \ No newline at end of file diff --git a/archiva-modules/archiva-maven/archiva-maven-repository/src/test/java/org/apache/archiva/repository/maven/metadata/storage/MockWagon.java b/archiva-modules/archiva-maven/archiva-maven-repository/src/test/java/org/apache/archiva/repository/maven/metadata/storage/MockWagon.java deleted file mode 100644 index 7da70c30c..000000000 --- a/archiva-modules/archiva-maven/archiva-maven-repository/src/test/java/org/apache/archiva/repository/maven/metadata/storage/MockWagon.java +++ /dev/null @@ -1,247 +0,0 @@ -package org.apache.archiva.repository.maven.metadata.storage; - -/* - * 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.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 -{ - @Override - public void get( String s, File file ) - throws TransferFailedException, ResourceDoesNotExistException, AuthorizationException - { - String sourceFile = getBasedir() + "/src/test/resources/" + s; - - try - { - FileUtils.copyFile( new File( sourceFile ), file ); - assert( file.exists() ); - } - catch( IOException e ) - { - throw new ResourceDoesNotExistException( e.getMessage() ); - } - } - - @Override - public boolean getIfNewer( String s, File file, long l ) - throws TransferFailedException, ResourceDoesNotExistException, AuthorizationException - { - return false; - } - - @Override - public void put( File file, String s ) - throws TransferFailedException, ResourceDoesNotExistException, AuthorizationException - { - - } - - @Override - public void putDirectory( File file, String s ) - throws TransferFailedException, ResourceDoesNotExistException, AuthorizationException - { - - } - - @Override - public boolean resourceExists( String s ) - throws TransferFailedException, AuthorizationException - { - return false; - } - - @Override - public List getFileList( String s ) - throws TransferFailedException, ResourceDoesNotExistException, AuthorizationException - { - return null; - } - - @Override - public boolean supportsDirectoryCopy() - { - return false; - } - - @Override - public Repository getRepository() - { - return null; - } - - @Override - public void connect( Repository repository ) - throws ConnectionException, AuthenticationException - { - - } - - @Override - public void connect( Repository repository, ProxyInfo proxyInfo ) - throws ConnectionException, AuthenticationException - { - - } - - @Override - public void connect( Repository repository, ProxyInfoProvider proxyInfoProvider ) - throws ConnectionException, AuthenticationException - { - - } - - @Override - public void connect( Repository repository, AuthenticationInfo authenticationInfo ) - throws ConnectionException, AuthenticationException - { - - } - - @Override - public void connect( Repository repository, AuthenticationInfo authenticationInfo, ProxyInfo proxyInfo ) - throws ConnectionException, AuthenticationException - { - - } - - @Override - public void connect( Repository repository, AuthenticationInfo authenticationInfo, - ProxyInfoProvider proxyInfoProvider ) - throws ConnectionException, AuthenticationException - { - - } - - @Deprecated - @Override - public void openConnection() - throws ConnectionException, AuthenticationException - { - - } - - @Override - public void disconnect() - throws ConnectionException - { - - } - - @Override - public void setTimeout( int i ) - { - - } - - @Override - public int getTimeout() - { - return 0; - } - - @Override - public void setReadTimeout( int timeoutValue ) - { - - } - - @Override - public int getReadTimeout() - { - return 0; - } - - @Override - public void addSessionListener( SessionListener sessionListener ) - { - - } - - @Override - public void removeSessionListener( SessionListener sessionListener ) - { - - } - - @Override - public boolean hasSessionListener( SessionListener sessionListener ) - { - return false; - } - - @Override - public void addTransferListener( TransferListener transferListener ) - { - - } - - @Override - public void removeTransferListener( TransferListener transferListener ) - { - - } - - @Override - public boolean hasTransferListener( TransferListener transferListener ) - { - return false; - } - - @Override - public boolean isInteractive() - { - return false; - } - - @Override - 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/archiva-maven/archiva-maven-repository/src/test/java/org/apache/archiva/repository/maven/metadata/storage/mock/MockConfiguration.java b/archiva-modules/archiva-maven/archiva-maven-repository/src/test/java/org/apache/archiva/repository/maven/metadata/storage/mock/MockConfiguration.java deleted file mode 100644 index 35896ba1f..000000000 --- a/archiva-modules/archiva-maven/archiva-maven-repository/src/test/java/org/apache/archiva/repository/maven/metadata/storage/mock/MockConfiguration.java +++ /dev/null @@ -1,211 +0,0 @@ -package org.apache.archiva.repository.maven.metadata.storage.mock; - -/* - * 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.components.registry.Registry; -import org.apache.archiva.components.registry.RegistryException; -import org.apache.archiva.components.registry.RegistryListener; -import org.apache.archiva.configuration.ArchivaConfiguration; -import org.apache.archiva.configuration.ArchivaRuntimeConfiguration; -import org.apache.archiva.configuration.Configuration; -import org.apache.archiva.configuration.ConfigurationListener; -import org.apache.archiva.configuration.FileType; -import org.apache.archiva.configuration.IndeterminateConfigurationException; -import org.apache.archiva.configuration.RepositoryScanningConfiguration; -import org.apache.commons.lang3.StringUtils; -import org.easymock.IMocksControl; -import org.springframework.stereotype.Service; - -import java.nio.file.Path; -import java.nio.file.Paths; -import java.util.ArrayList; -import java.util.HashSet; -import java.util.List; -import java.util.Locale; -import java.util.Set; - -import static org.easymock.EasyMock.createNiceControl; - -/** - * MockConfiguration - * - * - */ -@Service("archivaConfiguration#mock") -public class MockConfiguration - implements ArchivaConfiguration -{ - - private Configuration configuration = new Configuration(); - - private Set registryListeners = new HashSet(); - private Set configListeners = new HashSet(); - - private IMocksControl registryControl; - - private Registry registryMock; - - public MockConfiguration() - { - registryControl = createNiceControl(); - registryMock = registryControl.createMock( Registry.class ); - configuration.setArchivaRuntimeConfiguration(new ArchivaRuntimeConfiguration()); - configuration.getArchivaRuntimeConfiguration().addChecksumType("sha1"); - configuration.getArchivaRuntimeConfiguration().addChecksumType("sha256"); - configuration.getArchivaRuntimeConfiguration().addChecksumType("md5"); - RepositoryScanningConfiguration rpsc = new RepositoryScanningConfiguration( ); - FileType ft = new FileType( ); - ft.setId( "artifacts" ); - ArrayList plist = new ArrayList<>( ); - plist.add( "**/*.jar" ); - plist.add( "**/*.pom" ); - plist.add( "**/*.war" ); - ft.setPatterns( plist ); - rpsc.addFileType( ft ); - ArrayList ftList = new ArrayList<>( ); - ftList.add( ft ); - rpsc.setFileTypes( ftList ); - configuration.setRepositoryScanning( rpsc ); - } - - @Override - public void addChangeListener( RegistryListener listener ) - { - registryListeners.add( listener ); - } - - @Override - public void removeChangeListener( RegistryListener listener ) - { - registryListeners.remove( listener ); - } - - @Override - public Configuration getConfiguration() - { - return configuration; - } - - @Override - public void save( Configuration configuration ) - throws RegistryException - { - /* do nothing */ - } - - @Override - public void save( Configuration configuration, String eventTag ) throws RegistryException, IndeterminateConfigurationException - { - // do nothing - } - - public void triggerChange( String name, String value ) - { - for(RegistryListener listener: registryListeners) - { - try - { - listener.afterConfigurationChange( registryMock, name, value ); - } - catch ( Exception e ) - { - e.printStackTrace(); - } - } - } - - @Override - public void addListener( ConfigurationListener listener ) - { - configListeners.add(listener); - } - - @Override - public void removeListener( ConfigurationListener listener ) - { - configListeners.remove( listener ); - } - - @Override - public boolean isDefaulted() - { - return false; - } - - @Override - public void reload() - { - // no op - } - - @Override - public Locale getDefaultLocale( ) - { - return Locale.getDefault(); - } - - @Override - public List getLanguagePriorities( ) - { - return Locale.LanguageRange.parse( "en,fr,de" ); - } - - @Override - public Path getAppServerBaseDir() { - if (System.getProperties().containsKey("appserver.base")) { - return Paths.get(System.getProperty("appserver.base")); - } else { - return Paths.get(""); - } - } - - - @Override - public Path getRepositoryBaseDir() { - return getDataDirectory().resolve("repositories"); - } - - @Override - public Path getRemoteRepositoryBaseDir() { - return getDataDirectory().resolve("remotes"); - } - - @Override - public Path getRepositoryGroupBaseDir() { - return getDataDirectory().resolve("groups"); - } - - @Override - public Path getDataDirectory() { - if (configuration!=null && StringUtils.isNotEmpty(configuration.getArchivaRuntimeConfiguration().getDataDirectory())) { - return Paths.get(configuration.getArchivaRuntimeConfiguration().getDataDirectory()); - } else { - return getAppServerBaseDir().resolve("data"); - } - } - - @Override - public Registry getRegistry( ) - { - return null; - } - - -} diff --git a/archiva-modules/archiva-maven/archiva-maven-repository/src/test/java/org/apache/archiva/repository/maven/mock/ArchivaIndexManagerMock.java b/archiva-modules/archiva-maven/archiva-maven-repository/src/test/java/org/apache/archiva/repository/maven/mock/ArchivaIndexManagerMock.java deleted file mode 100644 index fa73fb9f5..000000000 --- a/archiva-modules/archiva-maven/archiva-maven-repository/src/test/java/org/apache/archiva/repository/maven/mock/ArchivaIndexManagerMock.java +++ /dev/null @@ -1,826 +0,0 @@ -package org.apache.archiva.repository.maven.mock; - -/* - * 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.filelock.DefaultFileLockManager; -import org.apache.archiva.common.utils.FileUtils; -import org.apache.archiva.common.utils.PathUtil; -import org.apache.archiva.configuration.ArchivaConfiguration; -import org.apache.archiva.indexer.ArchivaIndexManager; -import org.apache.archiva.indexer.ArchivaIndexingContext; -import org.apache.archiva.indexer.IndexCreationFailedException; -import org.apache.archiva.indexer.IndexUpdateFailedException; -import org.apache.archiva.indexer.UnsupportedBaseContextException; -import org.apache.archiva.proxy.ProxyRegistry; -import org.apache.archiva.maven.common.proxy.WagonFactory; -import org.apache.archiva.maven.common.proxy.WagonFactoryException; -import org.apache.archiva.maven.common.proxy.WagonFactoryRequest; -import org.apache.archiva.proxy.model.NetworkProxy; -import org.apache.archiva.repository.EditableRepository; -import org.apache.archiva.repository.ManagedRepository; -import org.apache.archiva.repository.RemoteRepository; -import org.apache.archiva.repository.Repository; -import org.apache.archiva.repository.RepositoryType; -import org.apache.archiva.repository.UnsupportedRepositoryTypeException; -import org.apache.archiva.repository.base.PasswordCredentials; -import org.apache.archiva.repository.features.IndexCreationFeature; -import org.apache.archiva.repository.features.RemoteIndexFeature; -import org.apache.archiva.repository.storage.StorageAsset; -import org.apache.archiva.repository.storage.fs.FilesystemAsset; -import org.apache.archiva.repository.storage.fs.FilesystemStorage; -import org.apache.commons.lang3.StringUtils; -import org.apache.maven.index.ArtifactContext; -import org.apache.maven.index.ArtifactContextProducer; -import org.apache.maven.index.DefaultScannerListener; -import org.apache.maven.index.Indexer; -import org.apache.maven.index.IndexerEngine; -import org.apache.maven.index.Scanner; -import org.apache.maven.index.ScanningRequest; -import org.apache.maven.index.ScanningResult; -import org.apache.maven.index.context.IndexCreator; -import org.apache.maven.index.context.IndexingContext; -import org.apache.maven.index.packer.IndexPacker; -import org.apache.maven.index.packer.IndexPackingRequest; -import org.apache.maven.index.updater.IndexUpdateRequest; -import org.apache.maven.index.updater.ResourceFetcher; -import org.apache.maven.index_shaded.lucene.index.IndexFormatTooOldException; -import org.apache.maven.wagon.ConnectionException; -import org.apache.maven.wagon.ResourceDoesNotExistException; -import org.apache.maven.wagon.StreamWagon; -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.TransferEvent; -import org.apache.maven.wagon.events.TransferListener; -import org.apache.maven.wagon.proxy.ProxyInfo; -import org.apache.maven.wagon.shared.http.AbstractHttpClientWagon; -import org.apache.maven.wagon.shared.http.HttpConfiguration; -import org.apache.maven.wagon.shared.http.HttpMethodConfiguration; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.stereotype.Service; - -import javax.inject.Inject; -import java.io.FileNotFoundException; -import java.io.IOException; -import java.io.InputStream; -import java.net.MalformedURLException; -import java.net.URI; -import java.nio.file.Files; -import java.nio.file.Path; -import java.nio.file.Paths; -import java.util.Collection; -import java.util.List; -import java.util.Map; -import java.util.concurrent.ConcurrentSkipListSet; -import java.util.stream.Collectors; - -/** - * @author Martin Stockhammer - */ -@Service("archivaIndexManager#maven") -public class ArchivaIndexManagerMock implements ArchivaIndexManager { - private static final Logger log = LoggerFactory.getLogger( ArchivaIndexManagerMock.class ); - - @Inject - private Indexer indexer; - - @Inject - private IndexerEngine indexerEngine; - - @Inject - private List indexCreators; - - @Inject - private IndexPacker indexPacker; - - @Inject - private Scanner scanner; - - @Inject - private ArchivaConfiguration archivaConfiguration; - - @Inject - private WagonFactory wagonFactory; - - @Inject - private ArtifactContextProducer artifactContextProducer; - - @Inject - private ProxyRegistry proxyRegistry; - - private ConcurrentSkipListSet activeContexts = new ConcurrentSkipListSet<>( ); - - private static final int WAIT_TIME = 100; - private static final int MAX_WAIT = 10; - - - public static IndexingContext getMvnContext(ArchivaIndexingContext context ) throws UnsupportedBaseContextException - { - if ( !context.supports( IndexingContext.class ) ) - { - log.error( "The provided archiva index context does not support the maven IndexingContext" ); - throw new UnsupportedBaseContextException( "The context does not support the Maven IndexingContext" ); - } - return context.getBaseContext( IndexingContext.class ); - } - - private Path getIndexPath( ArchivaIndexingContext ctx ) - { - return ctx.getPath( ).getFilePath(); - } - - @FunctionalInterface - interface IndexUpdateConsumer - { - - void accept( IndexingContext indexingContext ) throws IndexUpdateFailedException; - } - - /* - * This method is used to do some actions around the update execution code. And to make sure, that no other - * method is running on the same index. - */ - private void executeUpdateFunction( ArchivaIndexingContext context, IndexUpdateConsumer function ) throws IndexUpdateFailedException - { - IndexingContext indexingContext = null; - try - { - indexingContext = getMvnContext( context ); - } - catch ( UnsupportedBaseContextException e ) - { - throw new IndexUpdateFailedException( "Maven index is not supported by this context", e ); - } - final Path ctxPath = getIndexPath( context ); - int loop = MAX_WAIT; - boolean active = false; - while ( loop-- > 0 && !active ) - { - active = activeContexts.add( ctxPath ); - try - { - Thread.currentThread( ).sleep( WAIT_TIME ); - } - catch ( InterruptedException e ) - { - // Ignore this - } - } - if ( active ) - { - try - { - function.accept( indexingContext ); - } - finally - { - activeContexts.remove( ctxPath ); - } - } - else - { - throw new IndexUpdateFailedException( "Timeout while waiting for index release on context " + context.getId( ) ); - } - } - - @Override - public void pack( final ArchivaIndexingContext context ) throws IndexUpdateFailedException - { - executeUpdateFunction( context, indexingContext -> { - try - { - IndexPackingRequest request = new IndexPackingRequest( indexingContext, - indexingContext.acquireIndexSearcher( ).getIndexReader( ), - indexingContext.getIndexDirectoryFile( ) ); - indexPacker.packIndex( request ); - indexingContext.updateTimestamp( true ); - } - catch ( IOException e ) - { - log.error( "IOException while packing index of context " + context.getId( ) + ( StringUtils.isNotEmpty( e.getMessage( ) ) ? ": " + e.getMessage( ) : "" ) ); - throw new IndexUpdateFailedException( "IOException during update of " + context.getId( ), e ); - } - } - ); - - } - - @Override - public void scan(final ArchivaIndexingContext context) throws IndexUpdateFailedException - { - executeUpdateFunction( context, indexingContext -> { - DefaultScannerListener listener = new DefaultScannerListener( indexingContext, indexerEngine, true, null ); - ScanningRequest request = new ScanningRequest( indexingContext, listener ); - ScanningResult result = scanner.scan( request ); - if ( result.hasExceptions( ) ) - { - log.error( "Exceptions occured during index scan of " + context.getId( ) ); - result.getExceptions( ).stream( ).map( e -> e.getMessage( ) ).distinct( ).limit( 5 ).forEach( - s -> log.error( "Message: " + s ) - ); - } - - } ); - } - - @Override - public void update(final ArchivaIndexingContext context, final boolean fullUpdate) throws IndexUpdateFailedException - { - log.info( "start download remote index for remote repository {}", context.getRepository( ).getId( ) ); - URI remoteUpdateUri; - if ( !( context.getRepository( ) instanceof RemoteRepository) || !(context.getRepository().supportsFeature(RemoteIndexFeature.class)) ) - { - throw new IndexUpdateFailedException( "The context is not associated to a remote repository with remote index " + context.getId( ) ); - } else { - RemoteIndexFeature rif = context.getRepository().getFeature(RemoteIndexFeature.class).get(); - remoteUpdateUri = context.getRepository().getLocation().resolve(rif.getIndexUri()); - } - final RemoteRepository remoteRepository = (RemoteRepository) context.getRepository( ); - - executeUpdateFunction( context, - indexingContext -> { - try - { - // create a temp directory to download files - Path tempIndexDirectory = Paths.get( indexingContext.getIndexDirectoryFile( ).getParent( ), ".tmpIndex" ); - Path indexCacheDirectory = Paths.get( indexingContext.getIndexDirectoryFile( ).getParent( ), ".indexCache" ); - Files.createDirectories( indexCacheDirectory ); - if ( Files.exists( tempIndexDirectory ) ) - { - org.apache.archiva.common.utils.FileUtils.deleteDirectory( tempIndexDirectory ); - } - Files.createDirectories( tempIndexDirectory ); - tempIndexDirectory.toFile( ).deleteOnExit( ); - String baseIndexUrl = indexingContext.getIndexUpdateUrl( ); - - String wagonProtocol = remoteUpdateUri.toURL( ).getProtocol( ); - - NetworkProxy networkProxy = null; - if ( remoteRepository.supportsFeature( RemoteIndexFeature.class ) ) - { - RemoteIndexFeature rif = remoteRepository.getFeature( RemoteIndexFeature.class ).get( ); - if ( StringUtils.isNotBlank( rif.getProxyId( ) ) ) - { - networkProxy = proxyRegistry.getNetworkProxy( rif.getProxyId( ) ); - if ( networkProxy == null ) - { - log.warn( - "your remote repository is configured to download remote index trought a proxy we cannot find id:{}", - rif.getProxyId( ) ); - } - } - - final StreamWagon wagon = (StreamWagon) wagonFactory.getWagon( - new WagonFactoryRequest( wagonProtocol, remoteRepository.getExtraHeaders( ) ).networkProxy( - networkProxy ) - ); - int readTimeout = (int) rif.getDownloadTimeout( ).toMillis( ) * 1000; - wagon.setReadTimeout( readTimeout ); - wagon.setTimeout( (int) remoteRepository.getTimeout( ).toMillis( ) * 1000 ); - - if ( wagon instanceof AbstractHttpClientWagon) - { - HttpConfiguration httpConfiguration = new HttpConfiguration( ); - HttpMethodConfiguration httpMethodConfiguration = new HttpMethodConfiguration( ); - httpMethodConfiguration.setUsePreemptive( true ); - httpMethodConfiguration.setReadTimeout( readTimeout ); - httpConfiguration.setGet( httpMethodConfiguration ); - AbstractHttpClientWagon.class.cast( wagon ).setHttpConfiguration( httpConfiguration ); - } - - wagon.addTransferListener( new DownloadListener( ) ); - ProxyInfo proxyInfo = null; - if ( networkProxy != null ) - { - proxyInfo = new ProxyInfo( ); - proxyInfo.setType( networkProxy.getProtocol( ) ); - proxyInfo.setHost( networkProxy.getHost( ) ); - proxyInfo.setPort( networkProxy.getPort( ) ); - proxyInfo.setUserName( networkProxy.getUsername( ) ); - proxyInfo.setPassword(new String(networkProxy.getPassword())); - } - AuthenticationInfo authenticationInfo = null; - if ( remoteRepository.getLoginCredentials( ) != null && ( remoteRepository.getLoginCredentials( ) instanceof PasswordCredentials) ) - { - PasswordCredentials creds = (PasswordCredentials) remoteRepository.getLoginCredentials( ); - authenticationInfo = new AuthenticationInfo( ); - authenticationInfo.setUserName( creds.getUsername( ) ); - authenticationInfo.setPassword( new String( creds.getPassword( ) ) ); - } - wagon.connect( new org.apache.maven.wagon.repository.Repository( remoteRepository.getId( ), baseIndexUrl ), authenticationInfo, - proxyInfo ); - - Path indexDirectory = indexingContext.getIndexDirectoryFile( ).toPath( ); - if ( !Files.exists( indexDirectory ) ) - { - Files.createDirectories( indexDirectory ); - } - - ResourceFetcher resourceFetcher = - new WagonResourceFetcher( log, tempIndexDirectory, wagon, remoteRepository ); - IndexUpdateRequest request = new IndexUpdateRequest( indexingContext, resourceFetcher ); - request.setForceFullUpdate( fullUpdate ); - request.setLocalIndexCacheDir( indexCacheDirectory.toFile( ) ); - - // indexUpdater.fetchAndUpdateIndex( request ); - - indexingContext.updateTimestamp( true ); - } - - } - catch ( AuthenticationException e ) - { - log.error( "Could not login to the remote proxy for updating index of {}", remoteRepository.getId( ), e ); - throw new IndexUpdateFailedException( "Login in to proxy failed while updating remote repository " + remoteRepository.getId( ), e ); - } - catch ( ConnectionException e ) - { - log.error( "Connection error during index update for remote repository {}", remoteRepository.getId( ), e ); - throw new IndexUpdateFailedException( "Connection error during index update for remote repository " + remoteRepository.getId( ), e ); - } - catch ( MalformedURLException e ) - { - log.error( "URL for remote index update of remote repository {} is not correct {}", remoteRepository.getId( ), remoteUpdateUri, e ); - throw new IndexUpdateFailedException( "URL for remote index update of repository is not correct " + remoteUpdateUri, e ); - } - catch ( IOException e ) - { - log.error( "IOException during index update of remote repository {}: {}", remoteRepository.getId( ), e.getMessage( ), e ); - throw new IndexUpdateFailedException( "IOException during index update of remote repository " + remoteRepository.getId( ) - + ( StringUtils.isNotEmpty( e.getMessage( ) ) ? ": " + e.getMessage( ) : "" ), e ); - } - catch ( WagonFactoryException e ) - { - log.error( "Wagon for remote index download of {} could not be created: {}", remoteRepository.getId( ), e.getMessage( ), e ); - throw new IndexUpdateFailedException( "Error while updating the remote index of " + remoteRepository.getId( ), e ); - } - } ); - - } - - @Override - public void addArtifactsToIndex( final ArchivaIndexingContext context, final Collection artifactReference ) throws IndexUpdateFailedException - { - final StorageAsset ctxUri = context.getPath(); - executeUpdateFunction(context, indexingContext -> { - Collection artifacts = artifactReference.stream().map(r -> artifactContextProducer.getArtifactContext(indexingContext, Paths.get(ctxUri.getFilePath().toUri().resolve(r)).toFile())).collect(Collectors.toList()); - try { - indexer.addArtifactsToIndex(artifacts, indexingContext); - } catch (IOException e) { - log.error("IOException while adding artifact {}", e.getMessage(), e); - throw new IndexUpdateFailedException("Error occured while adding artifact to index of "+context.getId() - + (StringUtils.isNotEmpty(e.getMessage()) ? ": "+e.getMessage() : "")); - } - }); - } - - @Override - public void removeArtifactsFromIndex( ArchivaIndexingContext context, Collection artifactReference ) throws IndexUpdateFailedException - { - final StorageAsset ctxUri = context.getPath(); - executeUpdateFunction(context, indexingContext -> { - Collection artifacts = artifactReference.stream().map(r -> artifactContextProducer.getArtifactContext(indexingContext, Paths.get(ctxUri.getFilePath().toUri().resolve(r)).toFile())).collect(Collectors.toList()); - try { - indexer.deleteArtifactsFromIndex(artifacts, indexingContext); - } catch (IOException e) { - log.error("IOException while removing artifact {}", e.getMessage(), e); - throw new IndexUpdateFailedException("Error occured while removing artifact from index of "+context.getId() - + (StringUtils.isNotEmpty(e.getMessage()) ? ": "+e.getMessage() : "")); - } - }); - - } - - @Override - public boolean supportsRepository( RepositoryType type ) - { - return type == RepositoryType.MAVEN; - } - - @Override - public ArchivaIndexingContext createContext( Repository repository ) throws IndexCreationFailedException - { - log.debug("Creating context for repo {}, type: {}", repository.getId(), repository.getType()); - if ( repository.getType( ) != RepositoryType.MAVEN ) - { - throw new UnsupportedRepositoryTypeException( repository.getType( ) ); - } - IndexingContext mvnCtx = null; - try - { - if ( repository instanceof RemoteRepository ) - { - mvnCtx = createRemoteContext( (RemoteRepository) repository ); - } - else if ( repository instanceof ManagedRepository ) - { - mvnCtx = createManagedContext( (ManagedRepository) repository ); - } - } - catch ( IOException e ) - { - log.error( "IOException during context creation " + e.getMessage( ), e ); - throw new IndexCreationFailedException( "Could not create index context for repository " + repository.getId( ) - + ( StringUtils.isNotEmpty( e.getMessage( ) ) ? ": " + e.getMessage( ) : "" ), e ); - } - MavenIndexContextMock context = null; - try { - context = new MavenIndexContextMock( repository, mvnCtx ); - } catch (IOException e) { - throw new IndexCreationFailedException(e); - } - - return context; - } - - @Override - public ArchivaIndexingContext reset(ArchivaIndexingContext context) throws IndexUpdateFailedException { - ArchivaIndexingContext ctx; - executeUpdateFunction(context, indexingContext -> { - try { - indexingContext.close(true); - } catch (IOException e) { - log.warn("Index close failed"); - } - try { - FileUtils.deleteDirectory(context.getPath().getFilePath()); - } catch (IOException e) { - throw new IndexUpdateFailedException("Could not delete index files"); - } - }); - try { - Repository repo = context.getRepository(); - ctx = createContext(context.getRepository()); - if (repo instanceof EditableRepository) { - ((EditableRepository)repo).setIndexingContext(ctx); - } - } catch (IndexCreationFailedException e) { - throw new IndexUpdateFailedException("Could not create index"); - } - return ctx; - } - - @Override - public ArchivaIndexingContext move(ArchivaIndexingContext context, Repository repo) throws IndexCreationFailedException { - if (context==null) { - return null; - } - if (context.supports(IndexingContext.class)) { - try { - StorageAsset newPath = getIndexPath(repo); - IndexingContext ctx = context.getBaseContext(IndexingContext.class); - Path oldPath = ctx.getIndexDirectoryFile().toPath(); - if (oldPath.equals(newPath)) { - // Nothing to do, if path does not change - return context; - } - if (!Files.exists(oldPath)) { - return createContext(repo); - } else if (context.isEmpty()) { - context.close(); - return createContext(repo); - } else { - context.close(false); - Files.move(oldPath, newPath.getFilePath()); - return createContext(repo); - } - } catch (IOException e) { - log.error("IOException while moving index directory {}", e.getMessage(), e); - throw new IndexCreationFailedException("Could not recreated the index.", e); - } catch (UnsupportedBaseContextException e) { - throw new IndexCreationFailedException("The given context, is not a maven context."); - } - } else { - throw new IndexCreationFailedException("Bad context type. This is not a maven context."); - } - } - - @Override - public void updateLocalIndexPath(Repository repo) { - if (repo.supportsFeature(IndexCreationFeature.class)) { - IndexCreationFeature icf = repo.getFeature(IndexCreationFeature.class).get(); - try { - icf.setLocalIndexPath(getIndexPath(repo)); - } catch (IOException e) { - log.error("Could not set local index path for {}. New URI: {}", repo.getId(), icf.getIndexPath()); - } - } - } - - @Override - public ArchivaIndexingContext mergeContexts(Repository destinationRepo, List contexts, boolean packIndex) throws UnsupportedOperationException, IndexCreationFailedException { - return null; - } - - - - private StorageAsset getIndexPath( Repository repo) throws IOException { - IndexCreationFeature icf = repo.getFeature(IndexCreationFeature.class).get(); - Path repoDir = repo.getRoot().getFilePath(); - URI indexDir = icf.getIndexPath(); - String indexPath = indexDir.getPath(); - Path indexDirectory = null; - FilesystemStorage fsStorage = (FilesystemStorage) repo.getRoot().getStorage(); - if ( ! StringUtils.isEmpty(indexDir.toString( ) ) ) - { - - indexDirectory = PathUtil.getPathFromUri( indexDir ); - // not absolute so create it in repository directory - if ( indexDirectory.isAbsolute( ) ) - { - indexPath = indexDirectory.getFileName().toString(); - fsStorage = new FilesystemStorage(indexDirectory.getParent(), new DefaultFileLockManager()); - } - else - { - indexDirectory = repoDir.resolve( indexDirectory ); - } - } - else - { - indexDirectory = repoDir.resolve( ".index" ); - indexPath = ".index"; - } - - if ( !Files.exists( indexDirectory ) ) - { - Files.createDirectories( indexDirectory ); - } - return new FilesystemAsset( fsStorage, indexPath, indexDirectory ); - } - - private IndexingContext createRemoteContext(RemoteRepository remoteRepository ) throws IOException - { - Path appServerBase = archivaConfiguration.getAppServerBaseDir( ); - - String contextKey = "remote-" + remoteRepository.getId( ); - - - // create remote repository path - Path repoDir = remoteRepository.getRoot().getFilePath(); - if ( !Files.exists( repoDir ) ) - { - Files.createDirectories( repoDir ); - } - - StorageAsset indexDirectory = null; - - // is there configured indexDirectory ? - if ( remoteRepository.supportsFeature( RemoteIndexFeature.class ) ) - { - RemoteIndexFeature rif = remoteRepository.getFeature( RemoteIndexFeature.class ).get( ); - indexDirectory = getIndexPath(remoteRepository); - String remoteIndexUrl = calculateIndexRemoteUrl( remoteRepository.getLocation( ), rif ); - try - { - - return getIndexingContext( remoteRepository, contextKey, repoDir, indexDirectory, remoteIndexUrl ); - } - catch ( IndexFormatTooOldException e ) - { - // existing index with an old lucene format so we need to delete it!!! - // delete it first then recreate it. - log.warn( "the index of repository {} is too old we have to delete and recreate it", // - remoteRepository.getId( ) ); - org.apache.archiva.common.utils.FileUtils.deleteDirectory( indexDirectory.getFilePath() ); - return getIndexingContext( remoteRepository, contextKey, repoDir, indexDirectory, remoteIndexUrl ); - - } - } - else - { - throw new IOException( "No remote index defined" ); - } - } - - private IndexingContext getIndexingContext( Repository repository, String contextKey, Path repoDir, StorageAsset indexDirectory, String indexUrl ) throws IOException - { - return indexer.createIndexingContext( contextKey, repository.getId( ), repoDir.toFile( ), indexDirectory.getFilePath().toFile( ), - repository.getLocation( ) == null ? null : repository.getLocation( ).toString( ), - indexUrl, - true, false, - indexCreators ); - } - - private IndexingContext createManagedContext( ManagedRepository repository ) throws IOException - { - - IndexingContext context; - // take care first about repository location as can be relative - Path repositoryDirectory = repository.getRoot().getFilePath(); - - if ( !Files.exists( repositoryDirectory ) ) - { - try - { - Files.createDirectories( repositoryDirectory ); - } - catch ( IOException e ) - { - log.error( "Could not create directory {}", repositoryDirectory ); - } - } - - StorageAsset indexDirectory = null; - - if ( repository.supportsFeature( IndexCreationFeature.class ) ) - { - indexDirectory = getIndexPath(repository); - - String indexUrl = repositoryDirectory.toUri( ).toURL( ).toExternalForm( ); - try - { - context = getIndexingContext( repository, repository.getId( ), repositoryDirectory, indexDirectory, indexUrl ); - context.setSearchable( repository.isScanned( ) ); - } - catch ( IndexFormatTooOldException e ) - { - // existing index with an old lucene format so we need to delete it!!! - // delete it first then recreate it. - log.warn( "the index of repository {} is too old we have to delete and recreate it", // - repository.getId( ) ); - org.apache.archiva.common.utils.FileUtils.deleteDirectory( indexDirectory.getFilePath() ); - context = getIndexingContext( repository, repository.getId( ), repositoryDirectory, indexDirectory, indexUrl ); - context.setSearchable( repository.isScanned( ) ); - } - return context; - } - else - { - throw new IOException( "No repository index defined" ); - } - } - - private String calculateIndexRemoteUrl( URI baseUri, RemoteIndexFeature rif ) - { - if ( rif.getIndexUri( ) == null ) - { - return baseUri.resolve( ".index" ).toString( ); - } - else - { - return baseUri.resolve( rif.getIndexUri( ) ).toString( ); - } - } - - private static final class DownloadListener - implements TransferListener - { - private Logger log = LoggerFactory.getLogger( getClass( ) ); - - private String resourceName; - - private long startTime; - - private int totalLength = 0; - - @Override - public void transferInitiated( TransferEvent transferEvent ) - { - startTime = System.currentTimeMillis( ); - resourceName = transferEvent.getResource( ).getName( ); - log.debug( "initiate transfer of {}", resourceName ); - } - - @Override - public void transferStarted( TransferEvent transferEvent ) - { - this.totalLength = 0; - resourceName = transferEvent.getResource( ).getName( ); - log.info( "start transfer of {}", transferEvent.getResource( ).getName( ) ); - } - - @Override - public void transferProgress( TransferEvent transferEvent, byte[] buffer, int length ) - { - log.debug( "transfer of {} : {}/{}", transferEvent.getResource( ).getName( ), buffer.length, length ); - this.totalLength += length; - } - - @Override - public void transferCompleted( TransferEvent transferEvent ) - { - resourceName = transferEvent.getResource( ).getName( ); - long endTime = System.currentTimeMillis( ); - log.info( "end of transfer file {} {} kb: {}s", transferEvent.getResource( ).getName( ), - this.totalLength / 1024, ( endTime - startTime ) / 1000 ); - } - - @Override - public void transferError( TransferEvent transferEvent ) - { - log.info( "error of transfer file {}: {}", transferEvent.getResource( ).getName( ), - transferEvent.getException( ).getMessage( ), transferEvent.getException( ) ); - } - - @Override - public void debug( String message ) - { - log.debug( "transfer debug {}", message ); - } - } - - private static class WagonResourceFetcher - implements ResourceFetcher - { - - Logger log; - - Path tempIndexDirectory; - - Wagon wagon; - - RemoteRepository remoteRepository; - - private WagonResourceFetcher( Logger log, Path tempIndexDirectory, Wagon wagon, - RemoteRepository remoteRepository ) - { - this.log = log; - this.tempIndexDirectory = tempIndexDirectory; - this.wagon = wagon; - this.remoteRepository = remoteRepository; - } - - @Override - public void connect( String id, String url ) - throws IOException - { - //no op - } - - @Override - public void disconnect( ) - throws IOException - { - // no op - } - - @Override - public InputStream retrieve(String name ) - throws IOException, FileNotFoundException - { - try - { - log.info( "index update retrieve file, name:{}", name ); - Path file = tempIndexDirectory.resolve( name ); - Files.deleteIfExists( file ); - file.toFile( ).deleteOnExit( ); - wagon.get( addParameters( name, remoteRepository ), file.toFile( ) ); - return Files.newInputStream( file ); - } - catch ( AuthorizationException | TransferFailedException e ) - { - throw new IOException( e.getMessage( ), e ); - } - catch ( ResourceDoesNotExistException e ) - { - FileNotFoundException fnfe = new FileNotFoundException( e.getMessage( ) ); - fnfe.initCause( e ); - throw fnfe; - } - } - - // FIXME remove crappy copy/paste - protected String addParameters( String path, RemoteRepository remoteRepository ) - { - if ( remoteRepository.getExtraParameters( ).isEmpty( ) ) - { - return path; - } - - boolean question = false; - - StringBuilder res = new StringBuilder( path == null ? "" : path ); - - for ( Map.Entry entry : remoteRepository.getExtraParameters( ).entrySet( ) ) - { - if ( !question ) - { - res.append( '?' ).append( entry.getKey( ) ).append( '=' ).append( entry.getValue( ) ); - } - } - - return res.toString( ); - } - - } -} diff --git a/archiva-modules/archiva-maven/archiva-maven-repository/src/test/java/org/apache/archiva/repository/maven/mock/MavenIndexContextMock.java b/archiva-modules/archiva-maven/archiva-maven-repository/src/test/java/org/apache/archiva/repository/maven/mock/MavenIndexContextMock.java deleted file mode 100644 index 31a9772c0..000000000 --- a/archiva-modules/archiva-maven/archiva-maven-repository/src/test/java/org/apache/archiva/repository/maven/mock/MavenIndexContextMock.java +++ /dev/null @@ -1,148 +0,0 @@ -package org.apache.archiva.repository.maven.mock; - -/* - * 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.filelock.DefaultFileLockManager; -import org.apache.archiva.indexer.ArchivaIndexingContext; -import org.apache.archiva.repository.Repository; -import org.apache.archiva.repository.storage.StorageAsset; -import org.apache.archiva.repository.storage.fs.FilesystemStorage; -import org.apache.maven.index.context.IndexingContext; - -import java.io.IOException; -import java.nio.file.Files; -import java.nio.file.NoSuchFileException; -import java.sql.Date; -import java.time.ZonedDateTime; -import java.util.Set; - -/** - * Maven implementation of index context - */ -public class MavenIndexContextMock implements ArchivaIndexingContext { - - private boolean open = true; - private IndexingContext delegate; - private Repository repository; - private FilesystemStorage indexStorage; - - MavenIndexContextMock(Repository repository, IndexingContext delegate) throws IOException { - this.delegate = delegate; - this.repository = repository; - indexStorage = new FilesystemStorage(delegate.getIndexDirectoryFile().toPath(), new DefaultFileLockManager()); - - } - - @Override - public String getId() { - return delegate.getId(); - } - - @Override - public Repository getRepository() { - return repository; - } - - @Override - public StorageAsset getPath() { - return indexStorage.getRoot(); - } - - @Override - public boolean isEmpty() throws IOException { - return Files.list(delegate.getIndexDirectoryFile().toPath()).count()==0; - } - - @Override - public void commit() throws IOException { - delegate.commit(); - } - - @Override - public void rollback() throws IOException { - delegate.rollback(); - } - - @Override - public void optimize() throws IOException { - delegate.optimize(); - } - - @Override - public void close(boolean deleteFiles) throws IOException { - open = false; - try { - delegate.close(deleteFiles); - } catch (NoSuchFileException e) { - // Ignore missing directory - } - } - - @Override - public void close() throws IOException { - open = false; - try { - delegate.close(false); - } catch (NoSuchFileException e) { - // Ignore missing directory - } - } - - @Override - public boolean isOpen() { - return open; - } - - @Override - public void purge() throws IOException { - delegate.purge(); - } - - @Override - public boolean supports(Class clazz) { - return IndexingContext.class.equals(clazz); - } - - @SuppressWarnings( "unchecked" ) - @Override - public T getBaseContext(Class clazz) throws UnsupportedOperationException { - if (IndexingContext.class.equals(clazz)) { - return (T) delegate; - } else { - throw new UnsupportedOperationException("The class "+clazz+" is not supported by the maven indexer"); - } - } - - @Override - public Set getGroups() throws IOException { - return delegate.getAllGroups(); - } - - @Override - public void updateTimestamp(boolean save) throws IOException { - delegate.updateTimestamp(save); - } - - @Override - public void updateTimestamp(boolean save, ZonedDateTime time) throws IOException { - delegate.updateTimestamp(save, Date.from(time.toInstant())); - } - - -} diff --git a/archiva-modules/archiva-maven/archiva-maven-repository/src/test/java/org/apache/archiva/repository/maven/mock/MockRepositoryArchivaTaskScheduler.java b/archiva-modules/archiva-maven/archiva-maven-repository/src/test/java/org/apache/archiva/repository/maven/mock/MockRepositoryArchivaTaskScheduler.java deleted file mode 100644 index 97c7bc0f5..000000000 --- a/archiva-modules/archiva-maven/archiva-maven-repository/src/test/java/org/apache/archiva/repository/maven/mock/MockRepositoryArchivaTaskScheduler.java +++ /dev/null @@ -1,57 +0,0 @@ -package org.apache.archiva.repository.maven.mock; -/* - * 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.components.taskqueue.TaskQueueException; -import org.apache.archiva.scheduler.repository.model.RepositoryArchivaTaskScheduler; -import org.apache.archiva.scheduler.repository.model.RepositoryTask; -import org.springframework.stereotype.Service; - -/** - * @author Olivier Lamy - */ -@Service ("archivaTaskScheduler#repositoryMock") -public class MockRepositoryArchivaTaskScheduler - implements RepositoryArchivaTaskScheduler -{ - @Override - public boolean isProcessingRepositoryTask( String repositoryId ) - { - return false; - } - - @Override - public boolean isProcessingRepositoryTask( RepositoryTask task ) - { - return false; - } - - @Override - public void queueTask( RepositoryTask task ) - throws TaskQueueException - { - // no op - } - - @Override - public boolean unQueueTask( RepositoryTask task ) - throws TaskQueueException - { - return false; - } -} diff --git a/archiva-modules/archiva-maven/archiva-maven-repository/src/test/java/org/apache/archiva/repository/maven/mock/RepositoryRegistryMock.java b/archiva-modules/archiva-maven/archiva-maven-repository/src/test/java/org/apache/archiva/repository/maven/mock/RepositoryRegistryMock.java deleted file mode 100644 index c9fba72a6..000000000 --- a/archiva-modules/archiva-maven/archiva-maven-repository/src/test/java/org/apache/archiva/repository/maven/mock/RepositoryRegistryMock.java +++ /dev/null @@ -1,62 +0,0 @@ -package org.apache.archiva.repository.maven.mock; - -/* - * 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.repository.ManagedRepository; -import org.apache.archiva.repository.Repository; -import org.apache.archiva.repository.RepositoryException; -import org.apache.archiva.repository.base.ArchivaRepositoryRegistry; -import org.apache.archiva.repository.base.ConfigurationHandler; -import org.apache.archiva.repository.validation.RepositoryValidator; - -import java.util.List; -import java.util.Map; -import java.util.TreeMap; - -public class RepositoryRegistryMock extends ArchivaRepositoryRegistry -{ - - private Map managedRepositories = new TreeMap<>(); - - public RepositoryRegistryMock( ConfigurationHandler configurationHandler, List> validatorList ) - { - super( configurationHandler, validatorList ); - } - - @Override - public ManagedRepository putRepository(ManagedRepository managedRepository) throws RepositoryException - { - managedRepositories.put(managedRepository.getId(), managedRepository); - return managedRepository; - } - - @Override - public ManagedRepository getManagedRepository(String repoId) { - return managedRepositories.get(repoId); - } - - @Override - public Repository getRepository( String repoId) { - if (managedRepositories.containsKey(repoId)) { - return managedRepositories.get(repoId); - } else { - return null; - } - } -} diff --git a/archiva-modules/archiva-maven/archiva-maven-repository/src/test/java/org/apache/archiva/repository/maven/mock/TestMetadataResolver.java b/archiva-modules/archiva-maven/archiva-maven-repository/src/test/java/org/apache/archiva/repository/maven/mock/TestMetadataResolver.java deleted file mode 100644 index 59438bf78..000000000 --- a/archiva-modules/archiva-maven/archiva-maven-repository/src/test/java/org/apache/archiva/repository/maven/mock/TestMetadataResolver.java +++ /dev/null @@ -1,89 +0,0 @@ -package org.apache.archiva.repository.maven.mock; - -/* - * 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.metadata.model.ArtifactMetadata; -import org.apache.archiva.metadata.model.ProjectVersionMetadata; -import org.apache.archiva.metadata.model.ProjectVersionReference; -import org.apache.archiva.metadata.repository.MetadataResolutionException; -import org.apache.archiva.metadata.repository.MetadataResolver; -import org.apache.archiva.metadata.repository.RepositorySession; -import org.springframework.stereotype.Service; - -import java.util.Collection; - -// FIXME: remove - this is useless, better to mock it or avoid needing it -@Service( "metadataResolver#test" ) -public class TestMetadataResolver - implements MetadataResolver -{ - @Override - public ProjectVersionMetadata resolveProjectVersion( RepositorySession session, String repoId, String namespace, - String projectId, String projectVersion ) - throws MetadataResolutionException - { - return null; - } - - @Override - public Collection resolveProjectReferences( RepositorySession session, String repoId, - String namespace, String projectId, - String projectVersion ) - throws MetadataResolutionException - { - return null; - } - - @Override - public Collection resolveRootNamespaces( RepositorySession session, String repoId ) - throws MetadataResolutionException - { - return null; - } - - @Override - public Collection resolveNamespaces( RepositorySession session, String repoId, String namespace ) - throws MetadataResolutionException - { - return null; - } - - @Override - public Collection resolveProjects( RepositorySession session, String repoId, String namespace ) - throws MetadataResolutionException - { - return null; - } - - @Override - public Collection resolveProjectVersions( RepositorySession session, String repoId, String namespace, - String projectId ) - throws MetadataResolutionException - { - return null; - } - - @Override - public Collection resolveArtifacts( RepositorySession session, String repoId, String namespace, - String projectId, String projectVersion ) - throws MetadataResolutionException - { - return null; - } -} diff --git a/archiva-modules/archiva-maven/archiva-maven-repository/src/test/java/org/apache/archiva/repository/maven/mock/configuration/MockRepoAdmin.java b/archiva-modules/archiva-maven/archiva-maven-repository/src/test/java/org/apache/archiva/repository/maven/mock/configuration/MockRepoAdmin.java deleted file mode 100644 index 497553d27..000000000 --- a/archiva-modules/archiva-maven/archiva-maven-repository/src/test/java/org/apache/archiva/repository/maven/mock/configuration/MockRepoAdmin.java +++ /dev/null @@ -1,323 +0,0 @@ -package org.apache.archiva.repository.maven.mock.configuration; -/* - * 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.admin.model.AuditInformation; -import org.apache.archiva.admin.model.RepositoryAdminException; -import org.apache.archiva.admin.model.beans.ManagedRepository; -import org.apache.archiva.admin.model.beans.NetworkProxy; -import org.apache.archiva.admin.model.beans.ProxyConnector; -import org.apache.archiva.admin.model.beans.ProxyConnectorRule; -import org.apache.archiva.admin.model.beans.RemoteRepository; -import org.apache.archiva.admin.model.managed.ManagedRepositoryAdmin; -import org.apache.archiva.admin.model.networkproxy.NetworkProxyAdmin; -import org.apache.archiva.admin.model.proxyconnector.ProxyConnectorAdmin; -import org.apache.archiva.admin.model.proxyconnector.ProxyConnectorOrderComparator; -import org.apache.archiva.admin.model.remote.RemoteRepositoryAdmin; -import org.apache.archiva.configuration.ArchivaConfiguration; -import org.apache.archiva.configuration.ManagedRepositoryConfiguration; -import org.apache.archiva.configuration.ProxyConnectorConfiguration; -import org.apache.archiva.configuration.RemoteRepositoryConfiguration; -import org.apache.commons.lang3.StringUtils; -import org.modelmapper.ModelMapper; -import org.springframework.stereotype.Service; - -import javax.inject.Inject; -import javax.inject.Named; -import java.util.ArrayList; -import java.util.Collections; -import java.util.HashMap; -import java.util.Iterator; -import java.util.List; -import java.util.Locale; -import java.util.Map; - -/** - * @author Olivier Lamy - */ -@Service -public class MockRepoAdmin - implements RemoteRepositoryAdmin, ManagedRepositoryAdmin, ProxyConnectorAdmin, NetworkProxyAdmin -{ - @Inject - @Named ( "archivaConfiguration#test" ) - private ArchivaConfiguration archivaConfiguration; - - @Override - public List getRemoteRepositories() - throws RepositoryAdminException - { - List remoteRepositories = - new ArrayList<>( archivaConfiguration.getConfiguration().getRemoteRepositories().size() ); - for ( RemoteRepositoryConfiguration repositoryConfiguration : archivaConfiguration.getConfiguration().getRemoteRepositories() ) - { - RemoteRepository remoteRepository = - new RemoteRepository( Locale.getDefault(), repositoryConfiguration.getId(), repositoryConfiguration.getName(), - repositoryConfiguration.getUrl(), repositoryConfiguration.getLayout(), - repositoryConfiguration.getUsername(), repositoryConfiguration.getPassword(), - repositoryConfiguration.getTimeout() ); - remoteRepository.setDownloadRemoteIndex( repositoryConfiguration.isDownloadRemoteIndex() ); - remoteRepository.setRemoteIndexUrl( repositoryConfiguration.getRemoteIndexUrl() ); - remoteRepository.setCronExpression( repositoryConfiguration.getRefreshCronExpression() ); - remoteRepository.setIndexDirectory( repositoryConfiguration.getIndexDir() ); - remoteRepository.setRemoteDownloadNetworkProxyId( - repositoryConfiguration.getRemoteDownloadNetworkProxyId() ); - remoteRepository.setRemoteDownloadTimeout( repositoryConfiguration.getRemoteDownloadTimeout() ); - remoteRepository.setDownloadRemoteIndexOnStartup( - repositoryConfiguration.isDownloadRemoteIndexOnStartup() ); - remoteRepositories.add( remoteRepository ); - } - return remoteRepositories; - } - - @Override - public RemoteRepository getRemoteRepository( String repositoryId ) - throws RepositoryAdminException - { - for ( RemoteRepository remoteRepository : getRemoteRepositories() ) - { - if ( StringUtils.equals( repositoryId, remoteRepository.getId() ) ) - { - return remoteRepository; - } - } - return null; - } - - @Override - public Boolean deleteRemoteRepository( String repositoryId, AuditInformation auditInformation ) - throws RepositoryAdminException - { - return null; //To change body of implemented methods use File | Settings | File Templates. - } - - @Override - public Boolean addRemoteRepository( RemoteRepository remoteRepository, AuditInformation auditInformation ) - throws RepositoryAdminException - { - return null; //To change body of implemented methods use File | Settings | File Templates. - } - - @Override - public Boolean updateRemoteRepository( RemoteRepository remoteRepository, AuditInformation auditInformation ) - throws RepositoryAdminException - { - return null; //To change body of implemented methods use File | Settings | File Templates. - } - - @Override - public Map getRemoteRepositoriesAsMap() - throws RepositoryAdminException - { - return null; //To change body of implemented methods use File | Settings | File Templates. - } - - @Override - public List getManagedRepositories() - throws RepositoryAdminException - { - return null; //To change body of implemented methods use File | Settings | File Templates. - } - - @Override - public Map getManagedRepositoriesAsMap() - throws RepositoryAdminException - { - return null; //To change body of implemented methods use File | Settings | File Templates. - } - - @Override - public ManagedRepository getManagedRepository( String repositoryId ) - throws RepositoryAdminException - { - for ( ManagedRepositoryConfiguration repoConfig : archivaConfiguration.getConfiguration().getManagedRepositories() ) - { - if ( StringUtils.equals( repositoryId, repoConfig.getId() ) ) - { - return new ManagedRepository( Locale.getDefault(), repoConfig.getId(), repoConfig.getName(), repoConfig.getLocation(), - repoConfig.getLayout(), repoConfig.isSnapshots(), repoConfig.isReleases(), - repoConfig.isBlockRedeployments(), repoConfig.getRefreshCronExpression(), - repoConfig.getIndexDir(), repoConfig.isScanned(), - repoConfig.getRetentionPeriod(), repoConfig.getRetentionCount(), - repoConfig.isDeleteReleasedSnapshots(), false ); - } - } - return null; - } - - @Override - public Boolean deleteManagedRepository( String repositoryId, AuditInformation auditInformation, - boolean deleteContent ) - throws RepositoryAdminException - { - return null; //To change body of implemented methods use File | Settings | File Templates. - } - - @Override - public Boolean addManagedRepository( ManagedRepository managedRepository, boolean needStageRepo, - AuditInformation auditInformation ) - throws RepositoryAdminException - { - return null; //To change body of implemented methods use File | Settings | File Templates. - } - - @Override - public Boolean updateManagedRepository( ManagedRepository managedRepository, boolean needStageRepo, - AuditInformation auditInformation, boolean resetStats ) - throws RepositoryAdminException - { - return null; //To change body of implemented methods use File | Settings | File Templates. - } - - - @Override - public List getProxyConnectors() - throws RepositoryAdminException - { - List proxyConnectorConfigurations = - archivaConfiguration.getConfiguration().getProxyConnectors(); - List proxyConnectors = new ArrayList<>( proxyConnectorConfigurations.size() ); - for ( ProxyConnectorConfiguration configuration : proxyConnectorConfigurations ) - { - proxyConnectors.add( getProxyConnector( configuration ) ); - } - Collections.sort( proxyConnectors, ProxyConnectorOrderComparator.getInstance() ); - return proxyConnectors; - } - - @Override - public ProxyConnector getProxyConnector( String sourceRepoId, String targetRepoId ) - throws RepositoryAdminException - { - return null; //To change body of implemented methods use File | Settings | File Templates. - } - - @Override - public Boolean addProxyConnector( ProxyConnector proxyConnector, AuditInformation auditInformation ) - throws RepositoryAdminException - { - return null; //To change body of implemented methods use File | Settings | File Templates. - } - - @Override - public Boolean deleteProxyConnector( ProxyConnector proxyConnector, AuditInformation auditInformation ) - throws RepositoryAdminException - { - return null; //To change body of implemented methods use File | Settings | File Templates. - } - - @Override - public Boolean updateProxyConnector( ProxyConnector proxyConnector, AuditInformation auditInformation ) - throws RepositoryAdminException - { - return null; - } - - @Override - public Map> getProxyConnectorAsMap() - throws RepositoryAdminException - { - Map> proxyConnectorMap = new HashMap<>(); - - Iterator it = getProxyConnectors().iterator(); - while ( it.hasNext() ) - { - ProxyConnector proxyConfig = it.next(); - String key = proxyConfig.getSourceRepoId(); - - List connectors = proxyConnectorMap.get( key ); - if ( connectors == null ) - { - connectors = new ArrayList<>( 1 ); - proxyConnectorMap.put( key, connectors ); - } - - connectors.add( proxyConfig ); - - Collections.sort( connectors, ProxyConnectorOrderComparator.getInstance() ); - } - - return proxyConnectorMap; - } - - @Override - public List getNetworkProxies() - throws RepositoryAdminException - { - return null; //To change body of implemented methods use File | Settings | File Templates. - } - - @Override - public NetworkProxy getNetworkProxy( String networkProxyId ) - throws RepositoryAdminException - { - return null; //To change body of implemented methods use File | Settings | File Templates. - } - - @Override - public void addNetworkProxy( NetworkProxy networkProxy, AuditInformation auditInformation ) - throws RepositoryAdminException - { - //To change body of implemented methods use File | Settings | File Templates. - } - - @Override - public void updateNetworkProxy( NetworkProxy networkProxy, AuditInformation auditInformation ) - throws RepositoryAdminException - { - //To change body of implemented methods use File | Settings | File Templates. - } - - @Override - public void deleteNetworkProxy( String networkProxyId, AuditInformation auditInformation ) - throws RepositoryAdminException - { - //To change body of implemented methods use File | Settings | File Templates. - } - - protected ProxyConnector getProxyConnector( ProxyConnectorConfiguration proxyConnectorConfiguration ) - { - return proxyConnectorConfiguration == null - ? null - : new ModelMapper().map( proxyConnectorConfiguration, ProxyConnector.class ); - } - - public List getProxyConnectorRules() - throws RepositoryAdminException - { - return null; - } - - public void addProxyConnectorRule( ProxyConnectorRule proxyConnectorRule ) - throws RepositoryAdminException - { - - } - - public void deleteProxyConnectorRule( ProxyConnectorRule proxyConnectorRule ) - throws RepositoryAdminException - { - - } - - public void updateProxyConnectorRule( ProxyConnectorRule proxyConnectorRule ) - throws RepositoryAdminException - { - - } -} diff --git a/archiva-modules/archiva-maven/archiva-maven-repository/src/test/java/org/apache/archiva/repository/maven/mock/configuration/StubConfiguration.java b/archiva-modules/archiva-maven/archiva-maven-repository/src/test/java/org/apache/archiva/repository/maven/mock/configuration/StubConfiguration.java deleted file mode 100644 index b63208f04..000000000 --- a/archiva-modules/archiva-maven/archiva-maven-repository/src/test/java/org/apache/archiva/repository/maven/mock/configuration/StubConfiguration.java +++ /dev/null @@ -1,159 +0,0 @@ -package org.apache.archiva.repository.maven.mock.configuration; - -/* - * 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.components.registry.Registry; -import org.apache.archiva.components.registry.RegistryException; -import org.apache.archiva.components.registry.RegistryListener; -import org.apache.archiva.configuration.ArchivaConfiguration; -import org.apache.archiva.configuration.Configuration; -import org.apache.archiva.configuration.ConfigurationListener; -import org.apache.archiva.configuration.IndeterminateConfigurationException; -import org.apache.archiva.configuration.RepositoryScanningConfiguration; -import org.apache.commons.lang3.StringUtils; -import org.springframework.stereotype.Service; - -import java.nio.file.Path; -import java.nio.file.Paths; -import java.util.List; -import java.util.Locale; - -@Service("archivaConfiguration#mocked") -public class StubConfiguration - implements ArchivaConfiguration -{ - private Configuration configuration = new Configuration(); - - StubConfiguration() { - configuration.setRepositoryScanning( new RepositoryScanningConfiguration() ); - } - - @Override - public Configuration getConfiguration() - { - return configuration; - } - - @Override - public void save( Configuration configuration ) - throws RegistryException, IndeterminateConfigurationException - { - this.configuration = configuration; - } - - @Override - public void save( Configuration configuration, String eventTag ) throws RegistryException, IndeterminateConfigurationException - { - this.configuration = configuration; - } - - @Override - public boolean isDefaulted() - { - return false; - } - - @Override - public void addListener( ConfigurationListener listener ) - { - // throw new UnsupportedOperationException(); - } - - @Override - public void removeListener( ConfigurationListener listener ) - { - throw new UnsupportedOperationException(); - } - - @Override - public void addChangeListener( RegistryListener listener ) - { - // throw new UnsupportedOperationException(); - } - - @Override - public void removeChangeListener( RegistryListener listener ) - { - throw new UnsupportedOperationException(); - } - - @Override - public void reload() - { - // no op - } - - @Override - public Locale getDefaultLocale( ) - { - return Locale.getDefault(); - } - - @Override - public List getLanguagePriorities( ) - { - return Locale.LanguageRange.parse( "en,fr,de" ); - } - - @Override - public Path getAppServerBaseDir() { - if (System.getProperties().containsKey("appserver.base")) { - return Paths.get(System.getProperty("appserver.base")); - } else { - return Paths.get(""); - } - } - - @Override - public Path getRepositoryBaseDir() { - return getDataDirectory().resolve("repositories"); - } - - @Override - public Path getRemoteRepositoryBaseDir() { - return getDataDirectory().resolve("remotes"); - } - - @Override - public Path getRepositoryGroupBaseDir( ) - { - return getDataDirectory().resolve("group"); - } - - @Override - public Path getDataDirectory() { - if (configuration!=null && configuration.getArchivaRuntimeConfiguration()!=null && StringUtils.isNotEmpty(configuration.getArchivaRuntimeConfiguration().getDataDirectory())) { - Path dataDir = Paths.get(configuration.getArchivaRuntimeConfiguration().getDataDirectory()); - if (dataDir.isAbsolute()) { - return dataDir; - } else { - return getAppServerBaseDir().resolve(dataDir); - } - } else { - return getAppServerBaseDir().resolve("data"); - } - - } - - @Override - public Registry getRegistry( ) - { - return null; - } -} diff --git a/archiva-modules/archiva-maven/archiva-maven-repository/src/test/java/org/apache/archiva/repository/maven/mock/configuration/TestConfiguration.java b/archiva-modules/archiva-maven/archiva-maven-repository/src/test/java/org/apache/archiva/repository/maven/mock/configuration/TestConfiguration.java deleted file mode 100644 index f88bd7cc7..000000000 --- a/archiva-modules/archiva-maven/archiva-maven-repository/src/test/java/org/apache/archiva/repository/maven/mock/configuration/TestConfiguration.java +++ /dev/null @@ -1,148 +0,0 @@ -package org.apache.archiva.repository.maven.mock.configuration; - -import org.apache.archiva.components.registry.Registry; -import org.apache.archiva.components.registry.RegistryException; -import org.apache.archiva.components.registry.RegistryListener; -import org.apache.archiva.configuration.ArchivaConfiguration; -import org.apache.archiva.configuration.Configuration; -import org.apache.archiva.configuration.ConfigurationListener; -import org.apache.archiva.configuration.IndeterminateConfigurationException; -import org.apache.commons.lang3.StringUtils; -import org.springframework.stereotype.Service; - -import java.nio.file.Path; -import java.nio.file.Paths; -import java.util.List; -import java.util.Locale; - -/* - * 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. - */ - -@Service("archivaConfiguration#test") -public class TestConfiguration - implements ArchivaConfiguration -{ - private Configuration configuration; - - @Override - public Configuration getConfiguration() - { - return configuration; - } - - @Override - public void save( Configuration configuration ) - throws RegistryException, IndeterminateConfigurationException - { - this.configuration = configuration; - } - - @Override - public void save( Configuration configuration, String eventTag ) throws RegistryException, IndeterminateConfigurationException - { - this.configuration = configuration; - } - - @Override - public boolean isDefaulted() - { - return false; - } - - @Override - public void addListener( ConfigurationListener listener ) - { - // no op - } - - @Override - public void removeListener( ConfigurationListener listener ) - { - // no op - } - - @Override - public void addChangeListener( RegistryListener listener ) - { - // no op - } - - @Override - public void removeChangeListener( RegistryListener listener ) - { - // no op - } - - @Override - public void reload() - { - // no op - } - - @Override - public Locale getDefaultLocale( ) - { - return Locale.getDefault(); - } - - @Override - public List getLanguagePriorities( ) - { - return Locale.LanguageRange.parse("en,fr,de"); - } - - @Override - public Path getAppServerBaseDir() { - if (System.getProperties().containsKey("appserver.base")) { - return Paths.get(System.getProperty("appserver.base")); - } else { - return Paths.get(""); - } - } - - @Override - public Path getRepositoryBaseDir() { - return getDataDirectory().resolve(""); - } - - @Override - public Path getRemoteRepositoryBaseDir() { - return getDataDirectory().resolve("remotes"); - } - - @Override - public Path getRepositoryGroupBaseDir() { - return getDataDirectory().resolve("groups"); - } - - @Override - public Path getDataDirectory() { - if (configuration!=null && configuration.getArchivaRuntimeConfiguration()!=null && - StringUtils.isNotEmpty(configuration.getArchivaRuntimeConfiguration().getDataDirectory())) { - return Paths.get(configuration.getArchivaRuntimeConfiguration().getDataDirectory()); - } else { - return getAppServerBaseDir().resolve("data"); - } - } - - @Override - public Registry getRegistry( ) - { - return null; - } -} diff --git a/archiva-modules/archiva-maven/archiva-maven-repository/src/test/resources/spring-context-merge.xml b/archiva-modules/archiva-maven/archiva-maven-repository/src/test/resources/spring-context-merge.xml index 8535a11c2..e4a0eb180 100644 --- a/archiva-modules/archiva-maven/archiva-maven-repository/src/test/resources/spring-context-merge.xml +++ b/archiva-modules/archiva-maven/archiva-maven-repository/src/test/resources/spring-context-merge.xml @@ -33,7 +33,7 @@ + class="org.apache.archiva.maven.repository.merge.Maven2RepositoryMergerTest" factory-method="getRepositorySessionFactory" /> \ No newline at end of file diff --git a/archiva-modules/archiva-maven/archiva-maven-repository/src/test/resources/spring-context-metadata-tools-test.xml b/archiva-modules/archiva-maven/archiva-maven-repository/src/test/resources/spring-context-metadata-tools-test.xml index 9d37539ba..1ed1fc58a 100644 --- a/archiva-modules/archiva-maven/archiva-maven-repository/src/test/resources/spring-context-metadata-tools-test.xml +++ b/archiva-modules/archiva-maven/archiva-maven-repository/src/test/resources/spring-context-metadata-tools-test.xml @@ -24,7 +24,7 @@ http://www.springframework.org/schema/beans/spring-beans-3.0.xsd" default-lazy-init="true"> - + diff --git a/archiva-modules/archiva-maven/archiva-maven-repository/src/test/resources/spring-context-repo-request-test.xml b/archiva-modules/archiva-maven/archiva-maven-repository/src/test/resources/spring-context-repo-request-test.xml index 3374e6bca..40d036ee4 100644 --- a/archiva-modules/archiva-maven/archiva-maven-repository/src/test/resources/spring-context-repo-request-test.xml +++ b/archiva-modules/archiva-maven/archiva-maven-repository/src/test/resources/spring-context-repo-request-test.xml @@ -27,7 +27,7 @@ http://www.springframework.org/schema/context/spring-context-3.0.xsd"> - + diff --git a/archiva-modules/archiva-maven/archiva-maven-repository/src/test/resources/spring-context-repository-conf.xml b/archiva-modules/archiva-maven/archiva-maven-repository/src/test/resources/spring-context-repository-conf.xml index 3915ff458..760087c47 100644 --- a/archiva-modules/archiva-maven/archiva-maven-repository/src/test/resources/spring-context-repository-conf.xml +++ b/archiva-modules/archiva-maven/archiva-maven-repository/src/test/resources/spring-context-repository-conf.xml @@ -27,7 +27,7 @@ http://www.springframework.org/schema/context/spring-context-3.0.xsd"> - + diff --git a/archiva-modules/archiva-maven/archiva-maven-repository/src/test/resources/spring-context-storage.xml b/archiva-modules/archiva-maven/archiva-maven-repository/src/test/resources/spring-context-storage.xml index f3c79fc49..bd9567de8 100644 --- a/archiva-modules/archiva-maven/archiva-maven-repository/src/test/resources/spring-context-storage.xml +++ b/archiva-modules/archiva-maven/archiva-maven-repository/src/test/resources/spring-context-storage.xml @@ -28,10 +28,10 @@ default-lazy-init="true"> - + - + diff --git a/archiva-modules/archiva-maven/archiva-maven-repository/src/test/resources/spring-context.xml b/archiva-modules/archiva-maven/archiva-maven-repository/src/test/resources/spring-context.xml index 0278de455..63dc0de2e 100644 --- a/archiva-modules/archiva-maven/archiva-maven-repository/src/test/resources/spring-context.xml +++ b/archiva-modules/archiva-maven/archiva-maven-repository/src/test/resources/spring-context.xml @@ -28,7 +28,7 @@ default-lazy-init="true"> - + diff --git a/archiva-modules/archiva-web/archiva-rest/archiva-rest-services/src/main/java/org/apache/archiva/rest/services/DefaultBrowseService.java b/archiva-modules/archiva-web/archiva-rest/archiva-rest-services/src/main/java/org/apache/archiva/rest/services/DefaultBrowseService.java index 641d3ad5f..abf2cc022 100644 --- a/archiva-modules/archiva-web/archiva-rest/archiva-rest-services/src/main/java/org/apache/archiva/rest/services/DefaultBrowseService.java +++ b/archiva-modules/archiva-web/archiva-rest/archiva-rest-services/src/main/java/org/apache/archiva/rest/services/DefaultBrowseService.java @@ -23,7 +23,7 @@ import org.apache.archiva.common.utils.VersionComparator; import org.apache.archiva.common.utils.VersionUtil; import org.apache.archiva.repository.ManagedRepositoryContent; import org.apache.archiva.repository.content.base.ArchivaItemSelector; -import org.apache.archiva.repository.maven.dependency.tree.DependencyTreeBuilder; +import org.apache.archiva.maven.repository.dependency.tree.DependencyTreeBuilder; import org.apache.archiva.maven.model.Artifact; import org.apache.archiva.maven.model.TreeEntry; import org.apache.archiva.metadata.generic.GenericMetadataFacet; @@ -32,8 +32,8 @@ import org.apache.archiva.metadata.model.MetadataFacet; import org.apache.archiva.metadata.model.ProjectVersionMetadata; import org.apache.archiva.metadata.model.ProjectVersionReference; import org.apache.archiva.metadata.repository.*; -import org.apache.archiva.repository.maven.metadata.storage.ArtifactMetadataVersionComparator; -import org.apache.archiva.repository.maven.metadata.storage.MavenProjectFacet; +import org.apache.archiva.maven.repository.metadata.storage.ArtifactMetadataVersionComparator; +import org.apache.archiva.maven.repository.metadata.storage.MavenProjectFacet; import org.apache.archiva.model.ArchivaRepositoryMetadata; import org.apache.archiva.proxy.ProxyRegistry; import org.apache.archiva.proxy.model.RepositoryProxyHandler; diff --git a/archiva-modules/archiva-web/archiva-webdav/src/test/java/org/apache/archiva/webdav/ArchivaDavResourceFactoryTest.java b/archiva-modules/archiva-web/archiva-webdav/src/test/java/org/apache/archiva/webdav/ArchivaDavResourceFactoryTest.java index 2140e8450..2de2b9a78 100644 --- a/archiva-modules/archiva-web/archiva-webdav/src/test/java/org/apache/archiva/webdav/ArchivaDavResourceFactoryTest.java +++ b/archiva-modules/archiva-web/archiva-webdav/src/test/java/org/apache/archiva/webdav/ArchivaDavResourceFactoryTest.java @@ -46,10 +46,10 @@ import org.apache.archiva.repository.RepositoryException; import org.apache.archiva.repository.RepositoryRegistry; import org.apache.archiva.repository.RepositoryType; import org.apache.archiva.repository.base.RepositoryHandlerDependencies; -import org.apache.archiva.repository.maven.content.ManagedDefaultRepositoryContent; -import org.apache.archiva.repository.maven.content.MavenContentHelper; -import org.apache.archiva.repository.maven.content.MavenRepositoryRequestInfo; -import org.apache.archiva.repository.maven.metadata.storage.ArtifactMappingProvider; +import org.apache.archiva.maven.repository.content.ManagedDefaultRepositoryContent; +import org.apache.archiva.maven.repository.content.MavenContentHelper; +import org.apache.archiva.maven.repository.content.MavenRepositoryRequestInfo; +import org.apache.archiva.maven.repository.metadata.storage.ArtifactMappingProvider; import org.apache.archiva.test.utils.ArchivaSpringJUnit4ClassRunner; import org.apache.commons.lang3.StringUtils; import org.apache.jackrabbit.webdav.DavException; diff --git a/archiva-modules/archiva-web/archiva-webdav/src/test/java/org/apache/archiva/webdav/DavResourceTest.java b/archiva-modules/archiva-web/archiva-webdav/src/test/java/org/apache/archiva/webdav/DavResourceTest.java index 6df8624f1..227a099c4 100644 --- a/archiva-modules/archiva-web/archiva-webdav/src/test/java/org/apache/archiva/webdav/DavResourceTest.java +++ b/archiva-modules/archiva-web/archiva-webdav/src/test/java/org/apache/archiva/webdav/DavResourceTest.java @@ -26,7 +26,7 @@ import org.apache.archiva.repository.content.LayoutException; import org.apache.archiva.repository.RepositoryRegistry; import org.apache.archiva.repository.storage.fs.FilesystemAsset; import org.apache.archiva.metadata.audit.AuditListener; -import org.apache.archiva.repository.maven.MavenManagedRepository; +import org.apache.archiva.maven.repository.MavenManagedRepository; import org.apache.archiva.repository.storage.fs.FilesystemStorage; import org.apache.archiva.test.utils.ArchivaSpringJUnit4ClassRunner; import org.apache.archiva.webdav.util.MimeTypes;