Java tutorial
package org.apache.archiva.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.checksum.ChecksumAlgorithm; import org.apache.archiva.checksum.ChecksummedFile; import org.apache.archiva.common.utils.PathUtil; 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.ConfigurationNames; import org.apache.archiva.configuration.FileTypes; import org.apache.archiva.configuration.ProxyConnectorConfiguration; import org.apache.archiva.maven2.metadata.MavenMetadataReader; import org.apache.archiva.model.ArchivaRepositoryMetadata; import org.apache.archiva.model.ArtifactReference; import org.apache.archiva.model.Plugin; import org.apache.archiva.model.ProjectReference; import org.apache.archiva.model.SnapshotVersion; import org.apache.archiva.model.VersionedReference; import org.apache.archiva.redback.components.registry.Registry; import org.apache.archiva.redback.components.registry.RegistryListener; import org.apache.archiva.repository.ContentNotFoundException; import org.apache.archiva.repository.ManagedRepositoryContent; import org.apache.archiva.repository.RemoteRepositoryContent; import org.apache.archiva.repository.layout.LayoutException; import org.apache.archiva.xml.XMLException; import org.apache.commons.collections.CollectionUtils; import org.apache.commons.io.FileUtils; import org.apache.commons.lang.StringUtils; import org.apache.commons.lang.math.NumberUtils; import org.apache.commons.lang.time.DateUtils; 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.io.File; import java.io.IOException; import java.text.ParseException; import java.text.SimpleDateFormat; import java.util.ArrayList; import java.util.Calendar; import java.util.Collection; import java.util.Collections; import java.util.Date; import java.util.HashMap; import java.util.HashSet; import java.util.Iterator; import java.util.LinkedHashSet; import java.util.List; import java.util.Map; import java.util.Set; import java.util.regex.Matcher; /** * MetadataTools * * */ @Service("metadataTools#default") public class MetadataTools implements RegistryListener { private Logger log = LoggerFactory.getLogger(getClass()); public static final String MAVEN_METADATA = "maven-metadata.xml"; public static final String MAVEN_ARCHETYPE_CATALOG = "archetype-catalog.xml"; private static final char PATH_SEPARATOR = '/'; private static final char GROUP_SEPARATOR = '.'; /** * */ @Inject @Named(value = "archivaConfiguration#default") private ArchivaConfiguration configuration; /** * */ @Inject @Named(value = "fileTypes") private FileTypes filetypes; private ChecksumAlgorithm[] algorithms = new ChecksumAlgorithm[] { ChecksumAlgorithm.SHA1, ChecksumAlgorithm.MD5 }; private List<String> artifactPatterns; private Map<String, Set<String>> proxies; private static final char NUMS[] = new char[] { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9' }; private SimpleDateFormat lastUpdatedFormat; public MetadataTools() { lastUpdatedFormat = new SimpleDateFormat("yyyyMMddHHmmss"); lastUpdatedFormat.setTimeZone(DateUtils.UTC_TIME_ZONE); } @Override public void afterConfigurationChange(Registry registry, String propertyName, Object propertyValue) { if (ConfigurationNames.isProxyConnector(propertyName)) { initConfigVariables(); } } @Override public void beforeConfigurationChange(Registry registry, String propertyName, Object propertyValue) { /* nothing to do */ } /** * Gather the set of snapshot versions found in a particular versioned reference. * * @return the Set of snapshot artifact versions found. * @throws LayoutException * @throws ContentNotFoundException */ public Set<String> gatherSnapshotVersions(ManagedRepositoryContent managedRepository, VersionedReference reference) throws LayoutException, IOException, ContentNotFoundException { Set<String> foundVersions = managedRepository.getVersions(reference); // Next gather up the referenced 'latest' versions found in any proxied repositories // maven-metadata-${proxyId}.xml files that may be present. // Does this repository have a set of remote proxied repositories? Set<String> proxiedRepoIds = this.proxies.get(managedRepository.getId()); if (CollectionUtils.isNotEmpty(proxiedRepoIds)) { String baseVersion = VersionUtil.getBaseVersion(reference.getVersion()); baseVersion = baseVersion.substring(0, baseVersion.indexOf(VersionUtil.SNAPSHOT) - 1); // Add in the proxied repo version ids too. Iterator<String> it = proxiedRepoIds.iterator(); while (it.hasNext()) { String proxyId = it.next(); ArchivaRepositoryMetadata proxyMetadata = readProxyMetadata(managedRepository, reference, proxyId); if (proxyMetadata == null) { // There is no proxy metadata, skip it. continue; } // Is there some snapshot info? SnapshotVersion snapshot = proxyMetadata.getSnapshotVersion(); if (snapshot != null) { String timestamp = snapshot.getTimestamp(); int buildNumber = snapshot.getBuildNumber(); // Only interested in the timestamp + buildnumber. if (StringUtils.isNotBlank(timestamp) && (buildNumber > 0)) { foundVersions.add(baseVersion + "-" + timestamp + "-" + buildNumber); } } } } return foundVersions; } /** * Take a path to a maven-metadata.xml, and attempt to translate it to a VersionedReference. * * @param path * @return */ public VersionedReference toVersionedReference(String path) throws RepositoryMetadataException { if (!path.endsWith("/" + MAVEN_METADATA)) { throw new RepositoryMetadataException("Cannot convert to versioned reference, not a metadata file. "); } VersionedReference reference = new VersionedReference(); String normalizedPath = StringUtils.replace(path, "\\", "/"); String pathParts[] = StringUtils.split(normalizedPath, '/'); int versionOffset = pathParts.length - 2; int artifactIdOffset = versionOffset - 1; int groupIdEnd = artifactIdOffset - 1; reference.setVersion(pathParts[versionOffset]); if (!hasNumberAnywhere(reference.getVersion())) { // Scary check, but without it, all paths are version references; throw new RepositoryMetadataException( "Not a versioned reference, as version id on path has no number in it."); } reference.setArtifactId(pathParts[artifactIdOffset]); StringBuilder gid = new StringBuilder(); for (int i = 0; i <= groupIdEnd; i++) { if (i > 0) { gid.append("."); } gid.append(pathParts[i]); } reference.setGroupId(gid.toString()); return reference; } private boolean hasNumberAnywhere(String version) { return StringUtils.indexOfAny(version, NUMS) != (-1); } public ProjectReference toProjectReference(String path) throws RepositoryMetadataException { if (!path.endsWith("/" + MAVEN_METADATA)) { throw new RepositoryMetadataException("Cannot convert to versioned reference, not a metadata file. "); } ProjectReference reference = new ProjectReference(); String normalizedPath = StringUtils.replace(path, "\\", "/"); String pathParts[] = StringUtils.split(normalizedPath, '/'); // Assume last part of the path is the version. int artifactIdOffset = pathParts.length - 2; int groupIdEnd = artifactIdOffset - 1; reference.setArtifactId(pathParts[artifactIdOffset]); StringBuilder gid = new StringBuilder(); for (int i = 0; i <= groupIdEnd; i++) { if (i > 0) { gid.append("."); } gid.append(pathParts[i]); } reference.setGroupId(gid.toString()); return reference; } public String toPath(ProjectReference reference) { StringBuilder path = new StringBuilder(); path.append(formatAsDirectory(reference.getGroupId())).append(PATH_SEPARATOR); path.append(reference.getArtifactId()).append(PATH_SEPARATOR); path.append(MAVEN_METADATA); return path.toString(); } public String toPath(VersionedReference reference) { StringBuilder path = new StringBuilder(); path.append(formatAsDirectory(reference.getGroupId())).append(PATH_SEPARATOR); path.append(reference.getArtifactId()).append(PATH_SEPARATOR); if (reference.getVersion() != null) { // add the version only if it is present path.append(VersionUtil.getBaseVersion(reference.getVersion())).append(PATH_SEPARATOR); } path.append(MAVEN_METADATA); return path.toString(); } private String formatAsDirectory(String directory) { return directory.replace(GROUP_SEPARATOR, PATH_SEPARATOR); } /** * Adjusts a path for a metadata.xml file to its repository specific path. * * @param repository the repository to base new path off of. * @param path the path to the metadata.xml file to adjust the name of. * @return the newly adjusted path reference to the repository specific metadata path. */ public String getRepositorySpecificName(RemoteRepositoryContent repository, String path) { return getRepositorySpecificName(repository.getId(), path); } /** * Adjusts a path for a metadata.xml file to its repository specific path. * * @param proxyId the repository id to base new path off of. * @param path the path to the metadata.xml file to adjust the name of. * @return the newly adjusted path reference to the repository specific metadata path. */ public String getRepositorySpecificName(String proxyId, String path) { StringBuilder ret = new StringBuilder(); int idx = path.lastIndexOf('/'); if (idx > 0) { ret.append(path.substring(0, idx + 1)); } // TODO: need to filter out 'bad' characters from the proxy id. ret.append("maven-metadata-").append(proxyId).append(".xml"); return ret.toString(); } @PostConstruct public void initialize() { this.artifactPatterns = new ArrayList<>(); this.proxies = new HashMap<>(); initConfigVariables(); configuration.addChangeListener(this); } public ArchivaRepositoryMetadata readProxyMetadata(ManagedRepositoryContent managedRepository, ProjectReference reference, String proxyId) { String metadataPath = getRepositorySpecificName(proxyId, toPath(reference)); File metadataFile = new File(managedRepository.getRepoRoot(), metadataPath); if (!metadataFile.exists() || !metadataFile.isFile()) { // Nothing to do. return null. return null; } try { return MavenMetadataReader.read(metadataFile); } catch (XMLException e) { // TODO: [monitor] consider a monitor for this event. // TODO: consider a read-redo on monitor return code? log.warn("Unable to read metadata: {}", metadataFile.getAbsolutePath(), e); return null; } } public ArchivaRepositoryMetadata readProxyMetadata(ManagedRepositoryContent managedRepository, String logicalResource, String proxyId) { String metadataPath = getRepositorySpecificName(proxyId, logicalResource); File metadataFile = new File(managedRepository.getRepoRoot(), metadataPath); if (!metadataFile.exists() || !metadataFile.isFile()) { // Nothing to do. return null. return null; } try { return MavenMetadataReader.read(metadataFile); } catch (XMLException e) { // TODO: [monitor] consider a monitor for this event. // TODO: consider a read-redo on monitor return code? log.warn("Unable to read metadata: {}", metadataFile.getAbsolutePath(), e); return null; } } public ArchivaRepositoryMetadata readProxyMetadata(ManagedRepositoryContent managedRepository, VersionedReference reference, String proxyId) { String metadataPath = getRepositorySpecificName(proxyId, toPath(reference)); File metadataFile = new File(managedRepository.getRepoRoot(), metadataPath); if (!metadataFile.exists() || !metadataFile.isFile()) { // Nothing to do. return null. return null; } try { return MavenMetadataReader.read(metadataFile); } catch (XMLException e) { // TODO: [monitor] consider a monitor for this event. // TODO: consider a read-redo on monitor return code? log.warn("Unable to read metadata: {}", metadataFile.getAbsolutePath(), e); return null; } } public void updateMetadata(ManagedRepositoryContent managedRepository, String logicalResource) throws RepositoryMetadataException { final File metadataFile = new File(managedRepository.getRepoRoot(), logicalResource); ArchivaRepositoryMetadata metadata = null; //Gather and merge all metadata available List<ArchivaRepositoryMetadata> metadatas = getMetadatasForManagedRepository(managedRepository, logicalResource); for (ArchivaRepositoryMetadata proxiedMetadata : metadatas) { if (metadata == null) { metadata = proxiedMetadata; continue; } metadata = RepositoryMetadataMerge.merge(metadata, proxiedMetadata); } if (metadata == null) { log.debug("No metadata to update for {}", logicalResource); return; } Set<String> availableVersions = new HashSet<String>(); List<String> metadataAvailableVersions = metadata.getAvailableVersions(); if (metadataAvailableVersions != null) { availableVersions.addAll(metadataAvailableVersions); } availableVersions = findPossibleVersions(availableVersions, metadataFile.getParentFile()); if (availableVersions.size() > 0) { updateMetadataVersions(availableVersions, metadata); } RepositoryMetadataWriter.write(metadata, metadataFile); ChecksummedFile checksum = new ChecksummedFile(metadataFile); checksum.fixChecksums(algorithms); } /** * Skims the parent directory of a metadata in vain hope of finding * subdirectories that contain poms. * * @param metadataParentDirectory * @return origional set plus newley found versions */ private Set<String> findPossibleVersions(Set<String> versions, File metadataParentDirectory) { Set<String> result = new HashSet<String>(versions); for (File directory : metadataParentDirectory.listFiles()) { if (directory.isDirectory()) { for (File possiblePom : directory.listFiles()) { if (possiblePom.getName().endsWith(".pom")) { result.add(directory.getName()); } } } } return result; } private List<ArchivaRepositoryMetadata> getMetadatasForManagedRepository( ManagedRepositoryContent managedRepository, String logicalResource) { List<ArchivaRepositoryMetadata> metadatas = new ArrayList<>(); File file = new File(managedRepository.getRepoRoot(), logicalResource); if (file.exists()) { try { ArchivaRepositoryMetadata existingMetadata = MavenMetadataReader.read(file); if (existingMetadata != null) { metadatas.add(existingMetadata); } } catch (XMLException e) { log.debug("Could not read metadata at {}. Metadata will be removed.", file.getAbsolutePath()); FileUtils.deleteQuietly(file); } } Set<String> proxyIds = proxies.get(managedRepository.getId()); if (proxyIds != null) { for (String proxyId : proxyIds) { ArchivaRepositoryMetadata proxyMetadata = readProxyMetadata(managedRepository, logicalResource, proxyId); if (proxyMetadata != null) { metadatas.add(proxyMetadata); } } } return metadatas; } /** * Update the metadata to represent the all versions/plugins of * the provided groupId:artifactId project or group reference, * based off of information present in the repository, * the maven-metadata.xml files, and the proxy/repository specific * metadata file contents. * <p> * We must treat this as a group or a project metadata file as there is no way to know in advance * * @param managedRepository the managed repository where the metadata is kept. * @param reference the reference to update. * @throws LayoutException * @throws RepositoryMetadataException * @throws IOException * @throws ContentNotFoundException * @deprecated */ public void updateMetadata(ManagedRepositoryContent managedRepository, ProjectReference reference) throws LayoutException, RepositoryMetadataException, IOException, ContentNotFoundException { File metadataFile = new File(managedRepository.getRepoRoot(), toPath(reference)); long lastUpdated = getExistingLastUpdated(metadataFile); ArchivaRepositoryMetadata metadata = new ArchivaRepositoryMetadata(); metadata.setGroupId(reference.getGroupId()); metadata.setArtifactId(reference.getArtifactId()); // Gather up all versions found in the managed repository. Set<String> allVersions = managedRepository.getVersions(reference); // Gather up all plugins found in the managed repository. // TODO: do we know this information instead? // Set<Plugin> allPlugins = managedRepository.getPlugins( reference ); Set<Plugin> allPlugins; if (metadataFile.exists()) { try { allPlugins = new LinkedHashSet<Plugin>(MavenMetadataReader.read(metadataFile).getPlugins()); } catch (XMLException e) { throw new RepositoryMetadataException(e.getMessage(), e); } } else { allPlugins = new LinkedHashSet<Plugin>(); } // Does this repository have a set of remote proxied repositories? Set<String> proxiedRepoIds = this.proxies.get(managedRepository.getId()); if (CollectionUtils.isNotEmpty(proxiedRepoIds)) { // Add in the proxied repo version ids too. Iterator<String> it = proxiedRepoIds.iterator(); while (it.hasNext()) { String proxyId = it.next(); ArchivaRepositoryMetadata proxyMetadata = readProxyMetadata(managedRepository, reference, proxyId); if (proxyMetadata != null) { allVersions.addAll(proxyMetadata.getAvailableVersions()); allPlugins.addAll(proxyMetadata.getPlugins()); long proxyLastUpdated = getLastUpdated(proxyMetadata); lastUpdated = Math.max(lastUpdated, proxyLastUpdated); } } } if (!allVersions.isEmpty()) { updateMetadataVersions(allVersions, metadata); } else { // Add the plugins to the metadata model. metadata.setPlugins(new ArrayList<>(allPlugins)); // artifact ID was actually the last part of the group metadata.setGroupId(metadata.getGroupId() + "." + metadata.getArtifactId()); metadata.setArtifactId(null); } if (lastUpdated > 0) { metadata.setLastUpdatedTimestamp(toLastUpdatedDate(lastUpdated)); } // Save the metadata model to disk. RepositoryMetadataWriter.write(metadata, metadataFile); ChecksummedFile checksum = new ChecksummedFile(metadataFile); checksum.fixChecksums(algorithms); } private void updateMetadataVersions(Collection<String> allVersions, ArchivaRepositoryMetadata metadata) { // Sort the versions List<String> sortedVersions = new ArrayList<>(allVersions); Collections.sort(sortedVersions, VersionComparator.getInstance()); // Split the versions into released and snapshots. List<String> releasedVersions = new ArrayList<>(); List<String> snapshotVersions = new ArrayList<>(); for (String version : sortedVersions) { if (VersionUtil.isSnapshot(version)) { snapshotVersions.add(version); } else { releasedVersions.add(version); } } Collections.sort(releasedVersions, VersionComparator.getInstance()); Collections.sort(snapshotVersions, VersionComparator.getInstance()); String latestVersion = sortedVersions.get(sortedVersions.size() - 1); String releaseVersion = null; if (CollectionUtils.isNotEmpty(releasedVersions)) { releaseVersion = releasedVersions.get(releasedVersions.size() - 1); } // Add the versions to the metadata model. metadata.setAvailableVersions(sortedVersions); metadata.setLatestVersion(latestVersion); metadata.setReleasedVersion(releaseVersion); } private Date toLastUpdatedDate(long lastUpdated) { Calendar cal = Calendar.getInstance(DateUtils.UTC_TIME_ZONE); cal.setTimeInMillis(lastUpdated); return cal.getTime(); } private long toLastUpdatedLong(String timestampString) { try { Date date = lastUpdatedFormat.parse(timestampString); Calendar cal = Calendar.getInstance(DateUtils.UTC_TIME_ZONE); cal.setTime(date); return cal.getTimeInMillis(); } catch (ParseException e) { return 0; } } private long getLastUpdated(ArchivaRepositoryMetadata metadata) { if (metadata == null) { // Doesn't exist. return 0; } try { String lastUpdated = metadata.getLastUpdated(); if (StringUtils.isBlank(lastUpdated)) { // Not set. return 0; } Date lastUpdatedDate = lastUpdatedFormat.parse(lastUpdated); return lastUpdatedDate.getTime(); } catch (ParseException e) { // Bad format on the last updated string. return 0; } } private long getExistingLastUpdated(File metadataFile) { if (!metadataFile.exists()) { // Doesn't exist. return 0; } try { ArchivaRepositoryMetadata metadata = MavenMetadataReader.read(metadataFile); return getLastUpdated(metadata); } catch (XMLException e) { // Error. return 0; } } /** * Update the metadata based on the following rules. * <p> * 1) If this is a SNAPSHOT reference, then utilize the proxy/repository specific * metadata files to represent the current / latest SNAPSHOT available. * 2) If this is a RELEASE reference, and the metadata file does not exist, then * create the metadata file with contents required of the VersionedReference * * @param managedRepository the managed repository where the metadata is kept. * @param reference the versioned reference to update * @throws LayoutException * @throws RepositoryMetadataException * @throws IOException * @throws ContentNotFoundException * @deprecated */ public void updateMetadata(ManagedRepositoryContent managedRepository, VersionedReference reference) throws LayoutException, RepositoryMetadataException, IOException, ContentNotFoundException { File metadataFile = new File(managedRepository.getRepoRoot(), toPath(reference)); long lastUpdated = getExistingLastUpdated(metadataFile); ArchivaRepositoryMetadata metadata = new ArchivaRepositoryMetadata(); metadata.setGroupId(reference.getGroupId()); metadata.setArtifactId(reference.getArtifactId()); if (VersionUtil.isSnapshot(reference.getVersion())) { // Do SNAPSHOT handling. metadata.setVersion(VersionUtil.getBaseVersion(reference.getVersion())); // Gather up all of the versions found in the reference dir, and any // proxied maven-metadata.xml files. Set<String> snapshotVersions = gatherSnapshotVersions(managedRepository, reference); if (snapshotVersions.isEmpty()) { throw new ContentNotFoundException( "No snapshot versions found on reference [" + VersionedReference.toKey(reference) + "]."); } // sort the list to determine to aide in determining the Latest version. List<String> sortedVersions = new ArrayList<>(); sortedVersions.addAll(snapshotVersions); Collections.sort(sortedVersions, new VersionComparator()); String latestVersion = sortedVersions.get(sortedVersions.size() - 1); if (VersionUtil.isUniqueSnapshot(latestVersion)) { // The latestVersion will contain the full version string "1.0-alpha-5-20070821.213044-8" // This needs to be broken down into ${base}-${timestamp}-${build_number} Matcher m = VersionUtil.UNIQUE_SNAPSHOT_PATTERN.matcher(latestVersion); if (m.matches()) { metadata.setSnapshotVersion(new SnapshotVersion()); int buildNumber = NumberUtils.toInt(m.group(3), -1); metadata.getSnapshotVersion().setBuildNumber(buildNumber); Matcher mtimestamp = VersionUtil.TIMESTAMP_PATTERN.matcher(m.group(2)); if (mtimestamp.matches()) { String tsDate = mtimestamp.group(1); String tsTime = mtimestamp.group(2); long snapshotLastUpdated = toLastUpdatedLong(tsDate + tsTime); lastUpdated = Math.max(lastUpdated, snapshotLastUpdated); metadata.getSnapshotVersion().setTimestamp(m.group(2)); } } } else if (VersionUtil.isGenericSnapshot(latestVersion)) { // The latestVersion ends with the generic version string. // Example: 1.0-alpha-5-SNAPSHOT metadata.setSnapshotVersion(new SnapshotVersion()); /* Disabled due to decision in [MRM-535]. * Do not set metadata.lastUpdated to file.lastModified. * * Should this be the last updated timestamp of the file, or in the case of an * archive, the most recent timestamp in the archive? * ArtifactReference artifact = getFirstArtifact( managedRepository, reference ); if ( artifact == null ) { throw new IOException( "Not snapshot artifact found to reference in " + reference ); } File artifactFile = managedRepository.toFile( artifact ); if ( artifactFile.exists() ) { Date lastModified = new Date( artifactFile.lastModified() ); metadata.setLastUpdatedTimestamp( lastModified ); } */ } else { throw new RepositoryMetadataException( "Unable to process snapshot version <" + latestVersion + "> reference <" + reference + ">"); } } else { // Do RELEASE handling. metadata.setVersion(reference.getVersion()); } // Set last updated if (lastUpdated > 0) { metadata.setLastUpdatedTimestamp(toLastUpdatedDate(lastUpdated)); } // Save the metadata model to disk. RepositoryMetadataWriter.write(metadata, metadataFile); ChecksummedFile checksum = new ChecksummedFile(metadataFile); checksum.fixChecksums(algorithms); } private void initConfigVariables() { synchronized (this.artifactPatterns) { this.artifactPatterns.clear(); this.artifactPatterns.addAll(filetypes.getFileTypePatterns(FileTypes.ARTIFACTS)); } synchronized (proxies) { this.proxies.clear(); List<ProxyConnectorConfiguration> proxyConfigs = configuration.getConfiguration().getProxyConnectors(); for (ProxyConnectorConfiguration proxyConfig : proxyConfigs) { String key = proxyConfig.getSourceRepoId(); Set<String> remoteRepoIds = this.proxies.get(key); if (remoteRepoIds == null) { remoteRepoIds = new HashSet<String>(); } remoteRepoIds.add(proxyConfig.getTargetRepoId()); this.proxies.put(key, remoteRepoIds); } } } /** * Get the first Artifact found in the provided VersionedReference location. * * @param managedRepository the repository to search within. * @param reference the reference to the versioned reference to search within * @return the ArtifactReference to the first artifact located within the versioned reference. or null if * no artifact was found within the versioned reference. * @throws IOException if the versioned reference is invalid (example: doesn't exist, or isn't a directory) * @throws LayoutException */ public ArtifactReference getFirstArtifact(ManagedRepositoryContent managedRepository, VersionedReference reference) throws LayoutException, IOException { String path = toPath(reference); int idx = path.lastIndexOf('/'); if (idx > 0) { path = path.substring(0, idx); } File repoDir = new File(managedRepository.getRepoRoot(), path); if (!repoDir.exists()) { throw new IOException("Unable to gather the list of snapshot versions on a non-existant directory: " + repoDir.getAbsolutePath()); } if (!repoDir.isDirectory()) { throw new IOException("Unable to gather the list of snapshot versions on a non-directory: " + repoDir.getAbsolutePath()); } File repoFiles[] = repoDir.listFiles(); for (int i = 0; i < repoFiles.length; i++) { if (repoFiles[i].isDirectory()) { // Skip it. it's a directory. continue; } String relativePath = PathUtil.getRelative(managedRepository.getRepoRoot(), repoFiles[i]); if (filetypes.matchesArtifactPattern(relativePath)) { ArtifactReference artifact = managedRepository.toArtifactReference(relativePath); return artifact; } } // No artifact was found. return null; } public ArchivaConfiguration getConfiguration() { return configuration; } public void setConfiguration(ArchivaConfiguration configuration) { this.configuration = configuration; } public FileTypes getFiletypes() { return filetypes; } public void setFiletypes(FileTypes filetypes) { this.filetypes = filetypes; } }