/***************************************************************************** * 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.File; import java.io.FileNotFoundException; import java.io.IOException; import java.io.InputStream; import java.net.URI; import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; import javax.xml.parsers.ParserConfigurationException; import org.eclipse.buckminster.core.common.model.ExpandingProperties; import org.eclipse.buckminster.core.cspec.AbstractResolutionBuilder; import org.eclipse.buckminster.core.cspec.builder.CSpecBuilder; import org.eclipse.buckminster.core.cspec.builder.GroupBuilder; import org.eclipse.buckminster.core.ctype.AbstractComponentType; import org.eclipse.buckminster.core.ctype.MissingCSpecSourceException; import org.eclipse.buckminster.core.helpers.AccessibleByteArrayOutputStream; import org.eclipse.buckminster.core.helpers.FileUtils; import org.eclipse.buckminster.core.metadata.model.BOMNode; import org.eclipse.buckminster.core.reader.ICatalogReader; import org.eclipse.buckminster.core.reader.IComponentReader; import org.eclipse.buckminster.core.reader.IFileReader; import org.eclipse.buckminster.core.reader.IStreamConsumer; import org.eclipse.buckminster.core.reader.LocalReader; 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.core.version.VersionType; import org.eclipse.buckminster.maven.Messages; import org.eclipse.buckminster.runtime.BuckminsterException; import org.eclipse.buckminster.runtime.MonitorUtils; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.equinox.p2.metadata.Version; import org.w3c.dom.Document; import org.xml.sax.InputSource; import org.xml.sax.SAXException; import org.xml.sax.SAXParseException; /** * @author Thomas Hallgren */ class MavenCSpecBuilder extends AbstractResolutionBuilder implements IStreamConsumer<Document> { @Override public BOMNode build(IComponentReader[] readerHandle, boolean forResolutionAidOnly, IProgressMonitor monitor) throws CoreException { IComponentReader reader = readerHandle[0]; ProviderMatch ri = reader.getProviderMatch(); monitor.beginTask(null, 3000); monitor.subTask(Messages.generating_cspec_from_maven_artifact); try { Document pomDoc = null; IProgressMonitor subMon = MonitorUtils.subMonitor(monitor, 2000); if (reader instanceof MavenReader) { // We are reading from a maven repository. In that case, we will // allow a missing pom file. // pomDoc = ((MavenReader) reader).getPOMDocument(subMon); } else { // Some other reader is used. This reader is either reading a // source // directory (catalog reader) or a pom/project file directly. In // any // case, we consider a missing file an exceptional condition. // if (reader instanceof LocalReader) { File jarFile = new File(URI.create(ri.getRepositoryURI())); if (jarFile.isFile()) { File jarFolder = jarFile.getParentFile(); Version v = VersionHelper.createVersion(VersionType.TRIPLET, jarFolder.getName()); ri.setVersionMatch(new VersionMatch(v, null, null, null, null)); String jarName = jarFile.getName(); int lastDot = jarName.lastIndexOf('.'); if (lastDot > 0) { String pomName = jarName.substring(0, lastDot) + ".pom"; //$NON-NLS-1$ try { pomDoc = MavenReader.getPOMDocument(new File(jarFolder, pomName)); } catch (Exception e) { // Ignore } } } } else { try { if (reader instanceof ICatalogReader) { try { pomDoc = ((ICatalogReader) reader).readFile("pom.xml", this, subMon); //$NON-NLS-1$ } catch (FileNotFoundException e) { pomDoc = ((ICatalogReader) reader).readFile("project.xml", this, subMon); //$NON-NLS-1$ } } else pomDoc = ((IFileReader) reader).readFile(this, subMon); } catch (FileNotFoundException e2) { throw new MissingCSpecSourceException(reader.getProviderMatch()); } } } CSpecBuilder cspecBld = ri.createCSpec(); cspecBld.setComponentTypeID(MavenComponentType.ID); GroupBuilder archives = AbstractComponentType.addSelfAsJarArtifactGroups(cspecBld); if (pomDoc != null) { ExpandingProperties<String> properties = new ExpandingProperties<String>(); String packaging = MavenComponentType.addDependencies(reader, pomDoc, cspecBld, archives, properties); if (reader instanceof MavenReader && !"jar".equals(packaging)) //$NON-NLS-1$ ((MavenReader) reader).setPackaging(packaging); } applyExtensions(cspecBld, forResolutionAidOnly, reader, MonitorUtils.subMonitor(monitor, 1000)); return createNode(reader, cspecBld); } catch (IOException e) { throw BuckminsterException.wrap(e); } finally { monitor.done(); } } @Override public Document consumeStream(IComponentReader reader, String streamName, InputStream stream, IProgressMonitor monitor) throws CoreException, IOException { monitor.beginTask(streamName, 1); try { AccessibleByteArrayOutputStream buffer = new AccessibleByteArrayOutputStream(0x2000, 0x100000); FileUtils.copyFile(stream, buffer, new byte[0x1000], monitor); DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); DocumentBuilder docBld = factory.newDocumentBuilder(); try { 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 (SAXException e) { throw BuckminsterException.wrap(e); } catch (ParserConfigurationException e) { throw BuckminsterException.wrap(e); } finally { MonitorUtils.worked(monitor, 1); monitor.done(); } } }