/***************************************************************************** * Copyright (c) 2006-2013, Cloudsmith Inc. * The code, documentation and other materials contained herein have been * licensed under the Eclipse Public License - v 1.0 by the copyright holder * listed above, as the Initial Contributor under such license. The text of * such license is available at www.eclipse.org. *****************************************************************************/ package org.eclipse.buckminster.maven.internal; import java.io.FileNotFoundException; import java.net.URI; import java.net.URL; import java.util.ArrayList; import java.util.Collections; import java.util.List; import java.util.StringTokenizer; import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; import javax.xml.parsers.ParserConfigurationException; import org.eclipse.buckminster.core.ctype.IComponentType; import org.eclipse.buckminster.core.helpers.AccessibleByteArrayOutputStream; import org.eclipse.buckminster.core.reader.IVersionFinder; 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.ProviderMatch; import org.eclipse.buckminster.core.version.VersionHelper; import org.eclipse.buckminster.core.version.VersionMatch; import org.eclipse.buckminster.download.DownloadManager; import org.eclipse.buckminster.runtime.BuckminsterException; 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.NullProgressMonitor; import org.eclipse.ecf.core.security.IConnectContext; import org.eclipse.equinox.p2.metadata.Version; import org.eclipse.equinox.p2.metadata.VersionRange; import org.w3c.dom.Document; import org.w3c.dom.Element; import org.w3c.dom.NodeList; import org.xml.sax.InputSource; import org.xml.sax.SAXParseException; /** * @author Thomas Hallgren * */ public class Maven2ReaderType extends MavenReaderType { public static Document getMetadataDocument(DocumentBuilder docBld, URL url, LocalCache cache, IConnectContext cctx, IProgressMonitor monitor) throws CoreException, FileNotFoundException { try { AccessibleByteArrayOutputStream buffer = new AccessibleByteArrayOutputStream(0x2000, 0x100000); try { DownloadManager.readInto(url, cctx, buffer, monitor); return docBld.parse(buffer.getInputStream()); } catch (SAXParseException e) { String msg = e.getMessage(); if (msg == null || !msg.contains("UTF-8")) //$NON-NLS-1$ throw e; InputSource input = new InputSource(buffer.getInputStream()); input.setEncoding("ISO-8859-1"); //$NON-NLS-1$ docBld.reset(); return docBld.parse(input); } } catch (CoreException e) { docBld.reset(); throw e; } catch (FileNotFoundException e) { docBld.reset(); throw e; } catch (Exception e) { docBld.reset(); throw BuckminsterException.wrap(e); } } public static String getSnapshotVersion(Document doc, String version) { String v = null; Element versioningElement = getElement(doc, "versioning"); //$NON-NLS-1$ if (versioningElement != null) { Element snapshotElement = getElement(versioningElement, "snapshot"); //$NON-NLS-1$ if (snapshotElement != null) { Element buildNum = getElement(snapshotElement, "buildNumber"); //$NON-NLS-1$ if (buildNum != null) { Element ts = getElement(snapshotElement, "timestamp"); //$NON-NLS-1$ if (ts != null) v = version.substring(0, version.length() - 8) + ts.getTextContent() + '-' + buildNum.getTextContent(); } } } return v; } public static List<String> getVersions(Document doc) { List<String> versionList = null; Element versioningElement = getElement(doc, "versioning"); //$NON-NLS-1$ if (versioningElement != null) { Element versionsElement = getElement(versioningElement, "versions"); //$NON-NLS-1$ if (versionsElement != null) { NodeList versions = versionsElement.getElementsByTagName("version"); //$NON-NLS-1$ int top = versions.getLength(); for (int i = 0; i < top; i++) { if (versionList == null) versionList = new ArrayList<String>(); versionList.add(versions.item(i).getTextContent()); } } } return versionList == null ? Collections.<String> emptyList() : versionList; } private static Element getElement(Document doc, String elementName) { return getElement(doc.getElementsByTagName(elementName)); } private static Element getElement(Element elem, String elementName) { return elem == null ? null : getElement(elem.getElementsByTagName(elementName)); } private static Element getElement(NodeList nodeList) { return (nodeList != null && nodeList.getLength() > 0) ? (Element) nodeList.item(0) : null; } @Override public IVersionFinder getVersionFinder(Provider provider, IComponentType ctype, NodeQuery nodeQuery, IProgressMonitor monitor) throws CoreException { MonitorUtils.complete(monitor); return new Maven2VersionFinder(this, provider, ctype, nodeQuery); } @Override void appendArtifactFolder(StringBuilder pbld, IMapEntry mapEntry, VersionMatch vm) throws CoreException { String artifactPath = vm.getArtifactInfo(); appendEntryFolder(pbld, mapEntry); pbld.append(artifactPath, 0, artifactPath.lastIndexOf('/') + 1); } void appendEntryFolder(StringBuilder pbld, IMapEntry mapEntry) throws CoreException { StringTokenizer tokens = new StringTokenizer(mapEntry.getGroupId(), "."); //$NON-NLS-1$ while (tokens.hasMoreTokens()) appendFolder(pbld, tokens.nextToken()); appendFolder(pbld, mapEntry.getArtifactId()); } @Override void appendFileName(StringBuilder pbld, String artifactID, VersionMatch vm, String extension) throws CoreException { if (extension == null) { String artifactPath = vm.getArtifactInfo(); pbld.append(artifactPath, artifactPath.lastIndexOf('/') + 1, artifactPath.length()); } else { pbld.append(artifactID); pbld.append('-'); pbld.append(VersionHelper.getOriginal(vm.getVersion())); pbld.append(extension); } } @Override void appendPathToArtifact(StringBuilder pbld, IMapEntry mapEntry, VersionMatch vs) throws CoreException { appendEntryFolder(pbld, mapEntry); pbld.append(vs.getArtifactInfo()); } @Override void appendPomFolder(StringBuilder pbld, IMapEntry mapEntry, VersionMatch vs) throws CoreException { appendArtifactFolder(pbld, mapEntry, vs); } VersionMatch createVersionMatch(DocumentBuilder docBld, ILocationResolver resolver, IMapEntry mapEntry, VersionRange range, String versionStr) throws CoreException { URI uri = resolver.getURI(); StringBuilder pbld = new StringBuilder(); appendFolder(pbld, uri.getPath()); appendEntryFolder(pbld, mapEntry); String rootPath = pbld.toString(); String v = versionStr; if (v.endsWith("SNAPSHOT")) //$NON-NLS-1$ { try { LocalCache lc = getLocalCache(); Document doc = getMetadataDocument(docBld, createURL(uri, rootPath + v + "/" //$NON-NLS-1$ + "maven-metadata.xml"), lc, resolver.getConnectContext(), new NullProgressMonitor()); //$NON-NLS-1$ v = getSnapshotVersion(doc, v); if (v == null) return null; } catch (CoreException e) { resolver.logDecision(ResolverDecisionType.VERSION_REJECTED, v, e.getMessage()); return null; } catch (FileNotFoundException e) { // Snapshot not present. This is a valid condition. return null; } } Version version; if (range == null) version = MavenComponentType.createVersion(v); else { try { version = range.getFormat().parse(v); if (!range.isIncluded(version)) return null; } catch (IllegalArgumentException e) { return null; } } pbld.setLength(0); pbld.append(versionStr); pbld.append('/'); pbld.append(mapEntry.getArtifactId()); pbld.append('-'); pbld.append(VersionHelper.getOriginal(version)); if (mapEntry instanceof SourceMapEntry) pbld.append("-sources"); //$NON-NLS-1$ pbld.append(".jar"); //$NON-NLS-1$ return new VersionMatch(version, null, -1, null, pbld.toString()); } @Override VersionMatch createVersionMatch(ILocationResolver resolver, IMapEntry mapEntry, String versionStr) throws CoreException { if (versionStr == null) return super.createVersionMatch(resolver, mapEntry, versionStr); try { VersionMatch vm = createVersionMatch(DocumentBuilderFactory.newInstance().newDocumentBuilder(), resolver, mapEntry, null, versionStr); if (vm == null) vm = super.createVersionMatch(resolver, mapEntry, versionStr); return vm; } catch (ParserConfigurationException e) { throw BuckminsterException.wrap(e); } } @Override IPath getDefaultLocalRepoPath() { return Maven2VersionFinder.getDefaultLocalRepoPath(); } @Override String getMaterializationFolder() { return "maven2"; //$NON-NLS-1$ } @Override void setPackaging(ProviderMatch providerMatch, String packaging) { VersionMatch vm = providerMatch.getVersionMatch(); String artifactInfo = vm.getArtifactInfo(); int suffixDelim = artifactInfo.lastIndexOf('.'); artifactInfo = artifactInfo.substring(0, suffixDelim + 1) + packaging; providerMatch.setVersionMatch(new VersionMatch(vm.getVersion(), vm.getBranchOrTag(), vm.getRevision(), vm.getTimestamp(), artifactInfo)); } }