Java tutorial
package org.apache.maven.repository.legacy; /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ import java.io.File; import java.io.IOException; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; import java.util.HashMap; import java.util.LinkedHashMap; import java.util.List; import java.util.Map; import org.apache.maven.RepositoryUtils; import org.apache.maven.artifact.Artifact; import org.apache.maven.artifact.InvalidRepositoryException; import org.apache.maven.artifact.factory.ArtifactFactory; import org.apache.maven.artifact.metadata.ArtifactMetadata; import org.apache.maven.artifact.repository.ArtifactRepository; import org.apache.maven.repository.legacy.repository.ArtifactRepositoryFactory; import org.apache.maven.artifact.repository.ArtifactRepositoryPolicy; import org.apache.maven.artifact.repository.Authentication; import org.apache.maven.artifact.repository.layout.ArtifactRepositoryLayout; import org.apache.maven.artifact.resolver.ArtifactResolutionRequest; import org.apache.maven.artifact.resolver.ArtifactResolutionResult; import org.apache.maven.artifact.resolver.ArtifactResolver; import org.apache.maven.artifact.resolver.filter.ExcludesArtifactFilter; import org.apache.maven.artifact.versioning.InvalidVersionSpecificationException; import org.apache.maven.artifact.versioning.VersionRange; import org.apache.maven.model.Dependency; import org.apache.maven.model.Exclusion; import org.apache.maven.model.Plugin; import org.apache.maven.model.Repository; import org.apache.maven.model.RepositoryPolicy; import org.apache.maven.repository.DelegatingLocalArtifactRepository; import org.apache.maven.repository.LocalArtifactRepository; import org.apache.maven.repository.ArtifactTransferListener; import org.apache.maven.repository.MirrorSelector; import org.apache.maven.repository.Proxy; import org.apache.maven.repository.RepositorySystem; import org.apache.maven.repository.ArtifactDoesNotExistException; import org.apache.maven.repository.ArtifactTransferFailedException; import org.apache.maven.settings.Mirror; import org.apache.maven.settings.Server; import org.apache.maven.settings.building.SettingsProblem; import org.apache.maven.settings.crypto.DefaultSettingsDecryptionRequest; import org.apache.maven.settings.crypto.SettingsDecrypter; import org.apache.maven.settings.crypto.SettingsDecryptionRequest; import org.apache.maven.settings.crypto.SettingsDecryptionResult; import org.apache.maven.wagon.proxy.ProxyInfo; import org.apache.maven.wagon.proxy.ProxyUtils; import org.codehaus.plexus.PlexusContainer; import org.codehaus.plexus.component.annotations.Component; import org.codehaus.plexus.component.annotations.Requirement; import org.codehaus.plexus.component.repository.exception.ComponentLookupException; import org.codehaus.plexus.logging.Logger; import org.codehaus.plexus.util.StringUtils; import org.eclipse.aether.RepositorySystemSession; import org.eclipse.aether.repository.AuthenticationContext; import org.eclipse.aether.repository.AuthenticationSelector; import org.eclipse.aether.repository.ProxySelector; import org.eclipse.aether.repository.RemoteRepository; /** * @author Jason van Zyl */ @Component(role = RepositorySystem.class, hint = "default") public class LegacyRepositorySystem implements RepositorySystem { @Requirement private Logger logger; @Requirement private ArtifactFactory artifactFactory; @Requirement private ArtifactResolver artifactResolver; @Requirement private ArtifactRepositoryFactory artifactRepositoryFactory; @Requirement(role = ArtifactRepositoryLayout.class) private Map<String, ArtifactRepositoryLayout> layouts; @Requirement private WagonManager wagonManager; @Requirement private PlexusContainer plexus; @Requirement private MirrorSelector mirrorSelector; @Requirement private SettingsDecrypter settingsDecrypter; public Artifact createArtifact(String groupId, String artifactId, String version, String scope, String type) { return artifactFactory.createArtifact(groupId, artifactId, version, scope, type); } public Artifact createArtifact(String groupId, String artifactId, String version, String packaging) { return artifactFactory.createBuildArtifact(groupId, artifactId, version, packaging); } public Artifact createArtifactWithClassifier(String groupId, String artifactId, String version, String type, String classifier) { return artifactFactory.createArtifactWithClassifier(groupId, artifactId, version, type, classifier); } public Artifact createProjectArtifact(String groupId, String artifactId, String metaVersionId) { return artifactFactory.createProjectArtifact(groupId, artifactId, metaVersionId); } public Artifact createDependencyArtifact(Dependency d) { VersionRange versionRange; try { versionRange = VersionRange.createFromVersionSpec(d.getVersion()); } catch (InvalidVersionSpecificationException e) { // MNG-5368: Log a message instead of returning 'null' silently. this.logger.error(String.format("Invalid version specification '%s' creating dependency artifact '%s'.", d.getVersion(), d), e); return null; } Artifact artifact = artifactFactory.createDependencyArtifact(d.getGroupId(), d.getArtifactId(), versionRange, d.getType(), d.getClassifier(), d.getScope(), d.isOptional()); if (Artifact.SCOPE_SYSTEM.equals(d.getScope()) && d.getSystemPath() != null) { artifact.setFile(new File(d.getSystemPath())); } if (!d.getExclusions().isEmpty()) { List<String> exclusions = new ArrayList<>(); for (Exclusion exclusion : d.getExclusions()) { exclusions.add(exclusion.getGroupId() + ':' + exclusion.getArtifactId()); } artifact.setDependencyFilter(new ExcludesArtifactFilter(exclusions)); } return artifact; } public Artifact createExtensionArtifact(String groupId, String artifactId, String version) { VersionRange versionRange; try { versionRange = VersionRange.createFromVersionSpec(version); } catch (InvalidVersionSpecificationException e) { // MNG-5368: Log a message instead of returning 'null' silently. this.logger.error( String.format("Invalid version specification '%s' creating extension artifact '%s:%s:%s'.", version, groupId, artifactId, version), e); return null; } return artifactFactory.createExtensionArtifact(groupId, artifactId, versionRange); } public Artifact createParentArtifact(String groupId, String artifactId, String version) { return artifactFactory.createParentArtifact(groupId, artifactId, version); } public Artifact createPluginArtifact(Plugin plugin) { String version = plugin.getVersion(); if (StringUtils.isEmpty(version)) { version = "RELEASE"; } VersionRange versionRange; try { versionRange = VersionRange.createFromVersionSpec(version); } catch (InvalidVersionSpecificationException e) { // MNG-5368: Log a message instead of returning 'null' silently. this.logger.error(String.format("Invalid version specification '%s' creating plugin artifact '%s'.", version, plugin), e); return null; } return artifactFactory.createPluginArtifact(plugin.getGroupId(), plugin.getArtifactId(), versionRange); } public ArtifactRepositoryPolicy buildArtifactRepositoryPolicy(RepositoryPolicy policy) { boolean enabled = true; String updatePolicy = null; String checksumPolicy = null; if (policy != null) { enabled = policy.isEnabled(); if (policy.getUpdatePolicy() != null) { updatePolicy = policy.getUpdatePolicy(); } if (policy.getChecksumPolicy() != null) { checksumPolicy = policy.getChecksumPolicy(); } } return new ArtifactRepositoryPolicy(enabled, updatePolicy, checksumPolicy); } public ArtifactRepository createDefaultLocalRepository() throws InvalidRepositoryException { return createLocalRepository(RepositorySystem.defaultUserLocalRepository); } public ArtifactRepository createLocalRepository(File localRepository) throws InvalidRepositoryException { return createRepository("file://" + localRepository.toURI().getRawPath(), RepositorySystem.DEFAULT_LOCAL_REPO_ID, true, ArtifactRepositoryPolicy.UPDATE_POLICY_ALWAYS, true, ArtifactRepositoryPolicy.UPDATE_POLICY_ALWAYS, ArtifactRepositoryPolicy.CHECKSUM_POLICY_IGNORE); } public ArtifactRepository createDefaultRemoteRepository() throws InvalidRepositoryException { return createRepository(RepositorySystem.DEFAULT_REMOTE_REPO_URL, RepositorySystem.DEFAULT_REMOTE_REPO_ID, true, ArtifactRepositoryPolicy.UPDATE_POLICY_DAILY, false, ArtifactRepositoryPolicy.UPDATE_POLICY_DAILY, ArtifactRepositoryPolicy.CHECKSUM_POLICY_WARN); } public ArtifactRepository createLocalRepository(String url, String repositoryId) throws IOException { return createRepository(canonicalFileUrl(url), repositoryId, true, ArtifactRepositoryPolicy.UPDATE_POLICY_ALWAYS, true, ArtifactRepositoryPolicy.UPDATE_POLICY_ALWAYS, ArtifactRepositoryPolicy.CHECKSUM_POLICY_IGNORE); } private String canonicalFileUrl(String url) throws IOException { if (!url.startsWith("file:")) { url = "file://" + url; } else if (url.startsWith("file:") && !url.startsWith("file://")) { url = "file://" + url.substring("file:".length()); } // So now we have an url of the form file://<path> // We want to eliminate any relative path nonsense and lock down the path so we // need to fully resolve it before any sub-modules use the path. This can happen // when you are using a custom settings.xml that contains a relative path entry // for the local repository setting. File localRepository = new File(url.substring("file://".length())); if (!localRepository.isAbsolute()) { url = "file://" + localRepository.getCanonicalPath(); } return url; } public ArtifactResolutionResult resolve(ArtifactResolutionRequest request) { /* * Probably is not worth it, but here I make sure I restore request * to its original state. */ try { LocalArtifactRepository ideWorkspace = plexus.lookup(LocalArtifactRepository.class, LocalArtifactRepository.IDE_WORKSPACE); if (request.getLocalRepository() instanceof DelegatingLocalArtifactRepository) { DelegatingLocalArtifactRepository delegatingLocalRepository = (DelegatingLocalArtifactRepository) request .getLocalRepository(); LocalArtifactRepository orig = delegatingLocalRepository.getIdeWorkspace(); delegatingLocalRepository.setIdeWorkspace(ideWorkspace); try { return artifactResolver.resolve(request); } finally { delegatingLocalRepository.setIdeWorkspace(orig); } } else { ArtifactRepository localRepository = request.getLocalRepository(); DelegatingLocalArtifactRepository delegatingLocalRepository = new DelegatingLocalArtifactRepository( localRepository); delegatingLocalRepository.setIdeWorkspace(ideWorkspace); request.setLocalRepository(delegatingLocalRepository); try { return artifactResolver.resolve(request); } finally { request.setLocalRepository(localRepository); } } } catch (ComponentLookupException e) { // no ide workspace artifact resolution } return artifactResolver.resolve(request); } // public void addProxy( String protocol, String host, int port, String username, String password, // String nonProxyHosts ) // { // ProxyInfo proxyInfo = new ProxyInfo(); // proxyInfo.setHost( host ); // proxyInfo.setType( protocol ); // proxyInfo.setPort( port ); // proxyInfo.setNonProxyHosts( nonProxyHosts ); // proxyInfo.setUserName( username ); // proxyInfo.setPassword( password ); // // proxies.put( protocol, proxyInfo ); // // wagonManager.addProxy( protocol, host, port, username, password, nonProxyHosts ); // } public List<ArtifactRepository> getEffectiveRepositories(List<ArtifactRepository> repositories) { if (repositories == null) { return null; } Map<String, List<ArtifactRepository>> reposByKey = new LinkedHashMap<>(); for (ArtifactRepository repository : repositories) { String key = repository.getId(); List<ArtifactRepository> aliasedRepos = reposByKey.get(key); if (aliasedRepos == null) { aliasedRepos = new ArrayList<>(); reposByKey.put(key, aliasedRepos); } aliasedRepos.add(repository); } List<ArtifactRepository> effectiveRepositories = new ArrayList<>(); for (List<ArtifactRepository> aliasedRepos : reposByKey.values()) { List<ArtifactRepository> mirroredRepos = new ArrayList<>(); List<ArtifactRepositoryPolicy> releasePolicies = new ArrayList<>(aliasedRepos.size()); for (ArtifactRepository aliasedRepo : aliasedRepos) { releasePolicies.add(aliasedRepo.getReleases()); mirroredRepos.addAll(aliasedRepo.getMirroredRepositories()); } ArtifactRepositoryPolicy releasePolicy = getEffectivePolicy(releasePolicies); List<ArtifactRepositoryPolicy> snapshotPolicies = new ArrayList<>(aliasedRepos.size()); for (ArtifactRepository aliasedRepo : aliasedRepos) { snapshotPolicies.add(aliasedRepo.getSnapshots()); } ArtifactRepositoryPolicy snapshotPolicy = getEffectivePolicy(snapshotPolicies); ArtifactRepository aliasedRepo = aliasedRepos.get(0); ArtifactRepository effectiveRepository = createArtifactRepository(aliasedRepo.getId(), aliasedRepo.getUrl(), aliasedRepo.getLayout(), snapshotPolicy, releasePolicy); effectiveRepository.setAuthentication(aliasedRepo.getAuthentication()); effectiveRepository.setProxy(aliasedRepo.getProxy()); effectiveRepository.setMirroredRepositories(mirroredRepos); effectiveRepositories.add(effectiveRepository); } return effectiveRepositories; } private ArtifactRepositoryPolicy getEffectivePolicy(Collection<ArtifactRepositoryPolicy> policies) { ArtifactRepositoryPolicy effectivePolicy = null; for (ArtifactRepositoryPolicy policy : policies) { if (effectivePolicy == null) { effectivePolicy = new ArtifactRepositoryPolicy(policy); } else { effectivePolicy.merge(policy); } } return effectivePolicy; } public Mirror getMirror(ArtifactRepository repository, List<Mirror> mirrors) { return mirrorSelector.getMirror(repository, mirrors); } public void injectMirror(List<ArtifactRepository> repositories, List<Mirror> mirrors) { if (repositories != null && mirrors != null) { for (ArtifactRepository repository : repositories) { Mirror mirror = getMirror(repository, mirrors); injectMirror(repository, mirror); } } } private Mirror getMirror(RepositorySystemSession session, ArtifactRepository repository) { if (session != null) { org.eclipse.aether.repository.MirrorSelector selector = session.getMirrorSelector(); if (selector != null) { RemoteRepository repo = selector.getMirror(RepositoryUtils.toRepo(repository)); if (repo != null) { Mirror mirror = new Mirror(); mirror.setId(repo.getId()); mirror.setUrl(repo.getUrl()); mirror.setLayout(repo.getContentType()); return mirror; } } } return null; } public void injectMirror(RepositorySystemSession session, List<ArtifactRepository> repositories) { if (repositories != null && session != null) { for (ArtifactRepository repository : repositories) { Mirror mirror = getMirror(session, repository); injectMirror(repository, mirror); } } } private void injectMirror(ArtifactRepository repository, Mirror mirror) { if (mirror != null) { ArtifactRepository original = createArtifactRepository(repository.getId(), repository.getUrl(), repository.getLayout(), repository.getSnapshots(), repository.getReleases()); repository.setMirroredRepositories(Collections.singletonList(original)); repository.setId(mirror.getId()); repository.setUrl(mirror.getUrl()); if (StringUtils.isNotEmpty(mirror.getLayout())) { repository.setLayout(getLayout(mirror.getLayout())); } } } public void injectAuthentication(List<ArtifactRepository> repositories, List<Server> servers) { if (repositories != null) { Map<String, Server> serversById = new HashMap<>(); if (servers != null) { for (Server server : servers) { if (!serversById.containsKey(server.getId())) { serversById.put(server.getId(), server); } } } for (ArtifactRepository repository : repositories) { Server server = serversById.get(repository.getId()); if (server != null) { SettingsDecryptionRequest request = new DefaultSettingsDecryptionRequest(server); SettingsDecryptionResult result = settingsDecrypter.decrypt(request); server = result.getServer(); if (logger.isDebugEnabled()) { for (SettingsProblem problem : result.getProblems()) { logger.debug(problem.getMessage(), problem.getException()); } } Authentication authentication = new Authentication(server.getUsername(), server.getPassword()); authentication.setPrivateKey(server.getPrivateKey()); authentication.setPassphrase(server.getPassphrase()); repository.setAuthentication(authentication); } else { repository.setAuthentication(null); } } } } private Authentication getAuthentication(RepositorySystemSession session, ArtifactRepository repository) { if (session != null) { AuthenticationSelector selector = session.getAuthenticationSelector(); if (selector != null) { RemoteRepository repo = RepositoryUtils.toRepo(repository); org.eclipse.aether.repository.Authentication auth = selector.getAuthentication(repo); if (auth != null) { repo = new RemoteRepository.Builder(repo).setAuthentication(auth).build(); AuthenticationContext authCtx = AuthenticationContext.forRepository(session, repo); Authentication result = new Authentication(authCtx.get(AuthenticationContext.USERNAME), authCtx.get(AuthenticationContext.PASSWORD)); result.setPrivateKey(authCtx.get(AuthenticationContext.PRIVATE_KEY_PATH)); result.setPassphrase(authCtx.get(AuthenticationContext.PRIVATE_KEY_PASSPHRASE)); authCtx.close(); return result; } } } return null; } public void injectAuthentication(RepositorySystemSession session, List<ArtifactRepository> repositories) { if (repositories != null && session != null) { for (ArtifactRepository repository : repositories) { repository.setAuthentication(getAuthentication(session, repository)); } } } private org.apache.maven.settings.Proxy getProxy(ArtifactRepository repository, List<org.apache.maven.settings.Proxy> proxies) { if (proxies != null && repository.getProtocol() != null) { for (org.apache.maven.settings.Proxy proxy : proxies) { if (proxy.isActive() && repository.getProtocol().equalsIgnoreCase(proxy.getProtocol())) { if (StringUtils.isNotEmpty(proxy.getNonProxyHosts())) { ProxyInfo pi = new ProxyInfo(); pi.setNonProxyHosts(proxy.getNonProxyHosts()); org.apache.maven.wagon.repository.Repository repo = new org.apache.maven.wagon.repository.Repository( repository.getId(), repository.getUrl()); if (!ProxyUtils.validateNonProxyHosts(pi, repo.getHost())) { return proxy; } } else { return proxy; } } } } return null; } public void injectProxy(List<ArtifactRepository> repositories, List<org.apache.maven.settings.Proxy> proxies) { if (repositories != null) { for (ArtifactRepository repository : repositories) { org.apache.maven.settings.Proxy proxy = getProxy(repository, proxies); if (proxy != null) { SettingsDecryptionRequest request = new DefaultSettingsDecryptionRequest(proxy); SettingsDecryptionResult result = settingsDecrypter.decrypt(request); proxy = result.getProxy(); if (logger.isDebugEnabled()) { for (SettingsProblem problem : result.getProblems()) { logger.debug(problem.getMessage(), problem.getException()); } } Proxy p = new Proxy(); p.setHost(proxy.getHost()); p.setProtocol(proxy.getProtocol()); p.setPort(proxy.getPort()); p.setNonProxyHosts(proxy.getNonProxyHosts()); p.setUserName(proxy.getUsername()); p.setPassword(proxy.getPassword()); repository.setProxy(p); } else { repository.setProxy(null); } } } } private Proxy getProxy(RepositorySystemSession session, ArtifactRepository repository) { if (session != null) { ProxySelector selector = session.getProxySelector(); if (selector != null) { RemoteRepository repo = RepositoryUtils.toRepo(repository); org.eclipse.aether.repository.Proxy proxy = selector.getProxy(repo); if (proxy != null) { Proxy p = new Proxy(); p.setHost(proxy.getHost()); p.setProtocol(proxy.getType()); p.setPort(proxy.getPort()); if (proxy.getAuthentication() != null) { repo = new RemoteRepository.Builder(repo).setProxy(proxy).build(); AuthenticationContext authCtx = AuthenticationContext.forProxy(session, repo); p.setUserName(authCtx.get(AuthenticationContext.USERNAME)); p.setPassword(authCtx.get(AuthenticationContext.PASSWORD)); p.setNtlmDomain(authCtx.get(AuthenticationContext.NTLM_DOMAIN)); p.setNtlmHost(authCtx.get(AuthenticationContext.NTLM_WORKSTATION)); authCtx.close(); } return p; } } } return null; } public void injectProxy(RepositorySystemSession session, List<ArtifactRepository> repositories) { if (repositories != null && session != null) { for (ArtifactRepository repository : repositories) { repository.setProxy(getProxy(session, repository)); } } } public void retrieve(ArtifactRepository repository, File destination, String remotePath, ArtifactTransferListener transferListener) throws ArtifactTransferFailedException, ArtifactDoesNotExistException { try { wagonManager.getRemoteFile(repository, destination, remotePath, TransferListenerAdapter.newAdapter(transferListener), ArtifactRepositoryPolicy.CHECKSUM_POLICY_WARN, true); } catch (org.apache.maven.wagon.TransferFailedException e) { throw new ArtifactTransferFailedException(getMessage(e, "Error transferring artifact."), e); } catch (org.apache.maven.wagon.ResourceDoesNotExistException e) { throw new ArtifactDoesNotExistException(getMessage(e, "Requested artifact does not exist."), e); } } public void publish(ArtifactRepository repository, File source, String remotePath, ArtifactTransferListener transferListener) throws ArtifactTransferFailedException { try { wagonManager.putRemoteFile(repository, source, remotePath, TransferListenerAdapter.newAdapter(transferListener)); } catch (org.apache.maven.wagon.TransferFailedException e) { throw new ArtifactTransferFailedException(getMessage(e, "Error transferring artifact."), e); } } // // Artifact Repository Creation // public ArtifactRepository buildArtifactRepository(Repository repo) throws InvalidRepositoryException { if (repo != null) { String id = repo.getId(); if (StringUtils.isEmpty(id)) { throw new InvalidRepositoryException("Repository identifier missing", ""); } String url = repo.getUrl(); if (StringUtils.isEmpty(url)) { throw new InvalidRepositoryException("URL missing for repository " + id, id); } ArtifactRepositoryPolicy snapshots = buildArtifactRepositoryPolicy(repo.getSnapshots()); ArtifactRepositoryPolicy releases = buildArtifactRepositoryPolicy(repo.getReleases()); return createArtifactRepository(id, url, getLayout(repo.getLayout()), snapshots, releases); } else { return null; } } private ArtifactRepository createRepository(String url, String repositoryId, boolean releases, String releaseUpdates, boolean snapshots, String snapshotUpdates, String checksumPolicy) { ArtifactRepositoryPolicy snapshotsPolicy = new ArtifactRepositoryPolicy(snapshots, snapshotUpdates, checksumPolicy); ArtifactRepositoryPolicy releasesPolicy = new ArtifactRepositoryPolicy(releases, releaseUpdates, checksumPolicy); return createArtifactRepository(repositoryId, url, null, snapshotsPolicy, releasesPolicy); } public ArtifactRepository createArtifactRepository(String repositoryId, String url, ArtifactRepositoryLayout repositoryLayout, ArtifactRepositoryPolicy snapshots, ArtifactRepositoryPolicy releases) { if (repositoryLayout == null) { repositoryLayout = layouts.get("default"); } ArtifactRepository artifactRepository = artifactRepositoryFactory.createArtifactRepository(repositoryId, url, repositoryLayout, snapshots, releases); return artifactRepository; } private static String getMessage(Throwable error, String def) { if (error == null) { return def; } String msg = error.getMessage(); if (StringUtils.isNotEmpty(msg)) { return msg; } return getMessage(error.getCause(), def); } private ArtifactRepositoryLayout getLayout(String id) { ArtifactRepositoryLayout layout = layouts.get(id); if (layout == null) { layout = new UnknownRepositoryLayout(id, layouts.get("default")); } return layout; } /** * In the future, the legacy system might encounter repository types for which no layout components exists because * the actual communication with the repository happens via a repository connector. As a minimum, the legacy system * needs to retain the id of this layout so that the content type of the remote repository can still be accurately * described. */ static class UnknownRepositoryLayout implements ArtifactRepositoryLayout { private final String id; private final ArtifactRepositoryLayout fallback; UnknownRepositoryLayout(String id, ArtifactRepositoryLayout fallback) { this.id = id; this.fallback = fallback; } public String getId() { return id; } public String pathOf(Artifact artifact) { return fallback.pathOf(artifact); } public String pathOfLocalRepositoryMetadata(ArtifactMetadata metadata, ArtifactRepository repository) { return fallback.pathOfLocalRepositoryMetadata(metadata, repository); } public String pathOfRemoteRepositoryMetadata(ArtifactMetadata metadata) { return fallback.pathOfRemoteRepositoryMetadata(metadata); } @Override public String toString() { return getId(); } } }