/*******************************************************************************
* Copyright (c) 2004, 2006
* Thomas Hallgren, Kenneth Olwing, Mitch Sonies
* Pontus Rydin, Nils Unden, Peer Torngren
* The code, documentation and other materials contained herein have been
* licensed under the Eclipse Public License - v 1.0 by the individual
* copyright holders listed above, as Initial Contributors under such license.
* The text of such license is available at www.eclipse.org.
*******************************************************************************/
package org.eclipse.buckminster.maven.internal;
import java.net.URI;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;
import org.eclipse.buckminster.core.ctype.IComponentType;
import org.eclipse.buckminster.core.reader.URLCatalogReaderType;
import org.eclipse.buckminster.core.resolver.NodeQuery;
import org.eclipse.buckminster.core.resolver.ResolverDecisionType;
import org.eclipse.buckminster.core.rmap.model.Provider;
import org.eclipse.buckminster.core.version.AbstractVersionFinder;
import org.eclipse.buckminster.core.version.VersionHelper;
import org.eclipse.buckminster.core.version.VersionMatch;
import org.eclipse.buckminster.maven.Messages;
import org.eclipse.buckminster.runtime.MonitorUtils;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.Path;
import org.eclipse.equinox.p2.metadata.Version;
import org.eclipse.equinox.p2.metadata.VersionRange;
import org.eclipse.osgi.util.NLS;
/**
* The URL used by the MavenReader denotes the group directory within one
* specific repository. The format must be <br/>
* <code>[<schema>][//<authority>]<path to group>#<artifact></code>
* <br/>
* The ability to search trhough multiple repositories is obtained by using the
* <code>SearchPath</code> or the <code>ResourceMap</code>. The
*
* @author Thomas Hallgren
*/
public class MavenVersionFinder extends AbstractVersionFinder implements ILocationResolver {
private static final String[] allowedExtensions = new String[] { ".jar", ".mar" }; //$NON-NLS-1$ //$NON-NLS-2$
private final MavenReaderType readerType;
private final IMapEntry mapEntry;
private final URI uri;
private URL[] fileList;
public MavenVersionFinder(MavenReaderType readerType, Provider provider, IComponentType ctype, NodeQuery query) throws CoreException {
super(provider, ctype, query);
this.readerType = readerType;
this.uri = readerType.getURI(provider, query.getProperties());
this.mapEntry = MavenReaderType.getGroupAndArtifact(provider, query.getComponentRequest());
}
@Override
public void close() {
fileList = null;
}
@Override
public VersionMatch getBestVersion(IProgressMonitor monitor) throws CoreException {
VersionMatch best = null;
for (VersionMatch candidate : getComponentVersions(monitor))
best = getBestVersion(candidate, best);
return best;
}
@Override
public URI getURI() {
return uri;
}
VersionMatch getBestVersion(VersionMatch a, VersionMatch b) {
if (a == null)
return b;
if (b == null)
return a;
Version av = a.getVersion();
Version bv = b.getVersion();
VersionMatch selected;
VersionMatch rejected;
String msgFormat = Messages._0_has_no_version;
if (av == null) {
if (bv == null)
return a;
rejected = a;
selected = b;
} else if (bv == null) {
rejected = b;
selected = a;
} else {
msgFormat = Messages._0_is_a_better_match;
if (getQuery().compare(a, b) > 0) {
rejected = b;
selected = a;
} else {
rejected = a;
selected = b;
}
}
logDecision(ResolverDecisionType.MATCH_REJECTED, rejected, NLS.bind(msgFormat, selected));
return selected;
}
/**
* Returns an array of versions known to this repository.
*
* @return known versions or <code>null</code> if not applicable.
* @throws CoreException
*/
List<VersionMatch> getComponentVersions(IProgressMonitor monitor) throws CoreException {
NodeQuery query = getQuery();
VersionRange range = query.getVersionRange();
if (range == null)
range = VersionRange.emptyRange;
else {
if (range.getFormat().equals(VersionHelper.getOSGiFormat()))
//
// Convert the OSGi version to a Triplet version instead.
//
range = VersionHelper.createRange(MavenComponentType.getTripletFormat(), range.toString());
}
List<VersionMatch> versions = new ArrayList<VersionMatch>();
String artifact = mapEntry.getArtifactId() + '-';
int artifactLen = artifact.length();
for (URL url : getFileList(range, monitor)) {
IPath path = Path.fromPortableString(url.getPath());
int segCnt = path.segmentCount();
if (segCnt < 1)
continue;
String fileName = path.segment(segCnt - 1);
if (!fileName.startsWith(artifact))
continue;
String extension = null;
for (String allowedExtension : allowedExtensions) {
if (fileName.endsWith(allowedExtension)) {
extension = allowedExtension;
break;
}
}
if (extension == null)
continue;
String versionStr = fileName.substring(artifactLen, fileName.length() - extension.length());
VersionMatch versionMatch = MavenComponentType.createVersionMatch(versionStr, fileName + '/' + versionStr);
if (versionMatch != null && query.isMatch(versionMatch))
versions.add(versionMatch);
}
return versions;
}
IMapEntry getMapEntry() {
return mapEntry;
}
MavenReaderType getReaderType() {
return readerType;
}
private URL[] createFileList(VersionRange designator, IProgressMonitor monitor) throws CoreException {
StringBuilder pbld = new StringBuilder();
readerType.appendFolder(pbld, uri.getPath());
readerType.appendFolder(pbld, mapEntry.getGroupId());
readerType.appendFolder(pbld, "jars"); //$NON-NLS-1$
URL jarsURL = MavenReaderType.createURL(uri, pbld.toString());
return URLCatalogReaderType.list(jarsURL, getConnectContext(), monitor);
}
private URL[] getFileList(VersionRange designator, IProgressMonitor monitor) throws CoreException {
if (fileList == null)
fileList = createFileList(designator, monitor);
else
MonitorUtils.complete(monitor);
return fileList;
}
}