package io.takari.aether.localrepo;
/*******************************************************************************
* Copyright (c) 2010, 2011 Sonatype, Inc.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Sonatype, Inc. - initial API and implementation
*******************************************************************************/
import java.io.File;
import java.io.UnsupportedEncodingException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.SortedSet;
import java.util.TreeSet;
import org.eclipse.aether.RepositorySystemSession;
import org.eclipse.aether.artifact.Artifact;
import org.eclipse.aether.metadata.Metadata;
import org.eclipse.aether.repository.LocalArtifactRegistration;
import org.eclipse.aether.repository.LocalArtifactRequest;
import org.eclipse.aether.repository.LocalArtifactResult;
import org.eclipse.aether.repository.LocalMetadataRegistration;
import org.eclipse.aether.repository.LocalMetadataRequest;
import org.eclipse.aether.repository.LocalMetadataResult;
import org.eclipse.aether.repository.LocalRepository;
import org.eclipse.aether.repository.LocalRepositoryManager;
import org.eclipse.aether.repository.RemoteRepository;
/**
* A local repository manager that realizes the classical Maven 2.0 local repository.
*/
class BaseLocalRepositoryManager implements LocalRepositoryManager {
private final LocalRepository repository;
public BaseLocalRepositoryManager(File basedir) {
this(basedir, "simple");
}
public BaseLocalRepositoryManager(String basedir) {
this((basedir != null) ? new File(basedir) : null, "simple");
}
BaseLocalRepositoryManager(File basedir, String type) {
if (basedir == null) {
throw new IllegalArgumentException("base directory has not been specified");
}
repository = new LocalRepository(basedir.getAbsoluteFile(), type);
}
public LocalRepository getRepository() {
return repository;
}
String getPathForArtifact(Artifact artifact, boolean local) {
StringBuilder path = new StringBuilder(128);
path.append(artifact.getGroupId().replace('.', '/')).append('/');
path.append(artifact.getArtifactId()).append('/');
path.append(artifact.getBaseVersion()).append('/');
path.append(artifact.getArtifactId()).append('-');
if (local) {
path.append(artifact.getBaseVersion());
} else {
path.append(artifact.getVersion());
}
if (artifact.getClassifier().length() > 0) {
path.append('-').append(artifact.getClassifier());
}
if (artifact.getExtension().length() > 0) {
path.append('.').append(artifact.getExtension());
}
return path.toString();
}
public String getPathForLocalArtifact(Artifact artifact) {
return getPathForArtifact(artifact, true);
}
public String getPathForRemoteArtifact(Artifact artifact, RemoteRepository repository, String context) {
return getPathForArtifact(artifact, false);
}
public String getPathForLocalMetadata(Metadata metadata) {
return getPath(metadata, "local");
}
public String getPathForRemoteMetadata(Metadata metadata, RemoteRepository repository, String context) {
return getPath(metadata, getRepositoryKey(repository, context));
}
String getRepositoryKey(RemoteRepository repository, String context) {
String key;
if (repository.isRepositoryManager()) {
// repository serves dynamic contents, take request parameters into account for key
StringBuilder buffer = new StringBuilder(128);
buffer.append(repository.getId());
buffer.append('-');
SortedSet<String> subKeys = new TreeSet<String>();
for (RemoteRepository mirroredRepo : repository.getMirroredRepositories()) {
subKeys.add(mirroredRepo.getId());
}
SimpleDigest digest = new SimpleDigest();
digest.update(context);
for (String subKey : subKeys) {
digest.update(subKey);
}
buffer.append(digest.digest());
key = buffer.toString();
} else {
// repository serves static contents, its id is sufficient as key
key = repository.getId();
}
return key;
}
private String getPath(Metadata metadata, String repositoryKey) {
StringBuilder path = new StringBuilder(128);
if (metadata.getGroupId().length() > 0) {
path.append(metadata.getGroupId().replace('.', '/')).append('/');
if (metadata.getArtifactId().length() > 0) {
path.append(metadata.getArtifactId()).append('/');
if (metadata.getVersion().length() > 0) {
path.append(metadata.getVersion()).append('/');
}
}
}
path.append(insertRepositoryKey(metadata.getType(), repositoryKey));
return path.toString();
}
private String insertRepositoryKey(String filename, String repositoryKey) {
String result;
int idx = filename.indexOf('.');
if (idx < 0) {
result = filename + '-' + repositoryKey;
} else {
result = filename.substring(0, idx) + '-' + repositoryKey + filename.substring(idx);
}
return result;
}
public LocalArtifactResult find(RepositorySystemSession session, LocalArtifactRequest request) {
String path = getPathForArtifact(request.getArtifact(), false);
File file = new File(getRepository().getBasedir(), path);
LocalArtifactResult result = new LocalArtifactResult(request);
if (file.isFile()) {
result.setFile(file);
result.setAvailable(true);
}
return result;
}
public void add(RepositorySystemSession session, LocalArtifactRegistration request) {
// noop
}
@Override
public String toString() {
return String.valueOf(getRepository());
}
public LocalMetadataResult find(RepositorySystemSession session, LocalMetadataRequest request) {
LocalMetadataResult result = new LocalMetadataResult(request);
String path;
Metadata metadata = request.getMetadata();
String context = request.getContext();
RemoteRepository remote = request.getRepository();
if (remote != null) {
path = getPathForRemoteMetadata(metadata, remote, context);
} else {
path = getPathForLocalMetadata(metadata);
}
File file = new File(getRepository().getBasedir(), path);
if (file.isFile()) {
result.setFile(file);
}
return result;
}
public void add(RepositorySystemSession session, LocalMetadataRegistration request) {
// noop
}
//
// Just use Guava
//
class SimpleDigest {
private MessageDigest digest;
private long hash;
public SimpleDigest() {
try {
digest = MessageDigest.getInstance("SHA-1");
} catch (NoSuchAlgorithmException e) {
try {
digest = MessageDigest.getInstance("MD5");
} catch (NoSuchAlgorithmException ne) {
digest = null;
hash = 13;
}
}
}
public void update(String data) {
if (data == null || data.length() <= 0) {
return;
}
if (digest != null) {
try {
digest.update(data.getBytes("UTF-8"));
} catch (UnsupportedEncodingException e) {
// broken JVM
}
} else {
hash = hash * 31 + data.hashCode();
}
}
public String digest() {
if (digest != null) {
StringBuilder buffer = new StringBuilder(64);
byte[] bytes = digest.digest();
for (int i = 0; i < bytes.length; i++) {
int b = bytes[i] & 0xFF;
if (b < 0x10) {
buffer.append('0');
}
buffer.append(Integer.toHexString(b));
}
return buffer.toString();
} else {
return Long.toHexString(hash);
}
}
}
}