Skip to main content
summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorlaeubi2019-08-21 09:30:04 +0000
committerlaeubi2019-08-23 18:00:56 +0000
commitee19629117c1cc71ace05f403295eadef4c46c00 (patch)
treef0438c65428d509fb485883a9827280c1d80e96f
parent0dd5e1572083de96d41ada9c2cacfdbc8052a158 (diff)
downloadorg.eclipse.tycho.extras-ee19629117c1cc71ace05f403295eadef4c46c00.tar.gz
org.eclipse.tycho.extras-ee19629117c1cc71ace05f403295eadef4c46c00.tar.xz
org.eclipse.tycho.extras-ee19629117c1cc71ace05f403295eadef4c46c00.zip
Bug 550285 - support target plaform pomless build
+ refactoring for splitting Modelparsers into individual files Change-Id: I13718bfd9e48b8ebfb218ad752f3c0d3e93ce369 Signed-off-by: laeubi <laeubi@laeubi-soft.de>
-rw-r--r--tycho-extras-its/src/test/java/org/eclipse/tycho/extras/pomless/TychoPomlessITest.java2
-rw-r--r--tycho-extras-its/src/test/resources/testpomless/pom.xml46
-rw-r--r--tycho-extras-its/src/test/resources/testpomless/targetplatform/targetplatform.target10
-rw-r--r--tycho-pomless/src/main/java/org/eclipse/tycho/pomless/AbstractTychoMapping.java257
-rw-r--r--tycho-pomless/src/main/java/org/eclipse/tycho/pomless/AbstractXMLTychoMapping.java85
-rw-r--r--tycho-pomless/src/main/java/org/eclipse/tycho/pomless/TychoBundleMapping.java164
-rw-r--r--tycho-pomless/src/main/java/org/eclipse/tycho/pomless/TychoFeatureMapping.java66
-rw-r--r--tycho-pomless/src/main/java/org/eclipse/tycho/pomless/TychoMapping.java59
-rw-r--r--tycho-pomless/src/main/java/org/eclipse/tycho/pomless/TychoModelReader.java358
-rw-r--r--tycho-pomless/src/main/java/org/eclipse/tycho/pomless/TychoRepositoryMapping.java126
-rw-r--r--tycho-pomless/src/main/java/org/eclipse/tycho/pomless/TychoTargetMapping.java79
-rw-r--r--tycho-pomless/src/test/java/org/eclipse/tycho/pomless/TychoMappingTest.java4
-rw-r--r--tycho-pomless/src/test/java/org/eclipse/tycho/pomless/TychoModelReaderTest.java127
-rw-r--r--tycho-pomless/src/test/resources/mapping/precedence/META-INF/MANIFEST.MF6
-rw-r--r--tycho-pomless/src/test/resources/mapping/precedence/build.properties0
-rw-r--r--tycho-pomless/src/test/resources/mapping/simple/META-INF/MANIFEST.MF6
-rw-r--r--tycho-pomless/src/test/resources/mapping/simple/build.properties0
-rw-r--r--tycho-pomless/src/test/resources/modelreader/updatesites/pom.xml2
18 files changed, 896 insertions, 501 deletions
diff --git a/tycho-extras-its/src/test/java/org/eclipse/tycho/extras/pomless/TychoPomlessITest.java b/tycho-extras-its/src/test/java/org/eclipse/tycho/extras/pomless/TychoPomlessITest.java
index d3fb35f..44d4a49 100644
--- a/tycho-extras-its/src/test/java/org/eclipse/tycho/extras/pomless/TychoPomlessITest.java
+++ b/tycho-extras-its/src/test/java/org/eclipse/tycho/extras/pomless/TychoPomlessITest.java
@@ -35,7 +35,7 @@ public class TychoPomlessITest extends AbstractTychoExtrasIntegrationTest {
assertThat(new File(baseDir, "feature/target/pomless.feature-1.0.0-SNAPSHOT.jar"), isFile());
assertThat(new File(baseDir, "product/target/my.test.product.pomless-1.0.0.zip"), isFile());
isRepository(baseDir, "product");
- assertThat(new File(baseDir, "site1/target/testparent.site1.eclipse-repository-0.0.1-SNAPSHOT.zip"), isFile());
+ assertThat(new File(baseDir, "site1/target/site1.eclipse-repository-0.0.1-SNAPSHOT.zip"), isFile());
isRepository(baseDir, "site1");
}
diff --git a/tycho-extras-its/src/test/resources/testpomless/pom.xml b/tycho-extras-its/src/test/resources/testpomless/pom.xml
index 95ef4fc..b1ac4a3 100644
--- a/tycho-extras-its/src/test/resources/testpomless/pom.xml
+++ b/tycho-extras-its/src/test/resources/testpomless/pom.xml
@@ -1,15 +1,10 @@
<?xml version="1.0" encoding="UTF-8"?>
-<!--
- - Copyright (c) 2015 SAP SE and others.
- - 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:
- - SAP SE - initial API and implementation
- -->
-
+<!-- - Copyright (c) 2015 SAP SE and others. - 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:
+ - SAP SE - initial API and implementation -->
+
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
@@ -19,8 +14,8 @@
<version>0.0.1-SNAPSHOT</version>
<packaging>pom</packaging>
-
- <pluginRepositories>
+
+ <pluginRepositories>
<pluginRepository>
<id>tycho-snapshots</id>
<url>${tycho-snapshots-url}</url>
@@ -32,17 +27,10 @@
</snapshots>
</pluginRepository>
</pluginRepositories>
-
- <repositories>
- <repository>
- <id>p2.repo</id>
- <url>${p2.repo}</url>
- <layout>p2</layout>
- </repository>
- </repositories>
<modules>
<!-- look ma, no poms ! -->
+ <module>targetplatform</module>
<module>bundle1</module>
<module>bundle1.tests</module>
<module>feature</module>
@@ -58,7 +46,23 @@
<version>${tycho-version}</version>
<extensions>true</extensions>
</plugin>
+ <plugin>
+ <groupId>org.eclipse.tycho</groupId>
+ <artifactId>target-platform-configuration</artifactId>
+ <version>${tycho-version}</version>
+ <configuration>
+ <target>
+ <artifact>
+ <groupId>testParent.groupId</groupId>
+ <artifactId>targetplatform</artifactId>
+ <version>0.0.1-SNAPSHOT</version>
+ </artifact>
+ </target>
+ </configuration>
+ </plugin>
</plugins>
</build>
+
+
</project>
diff --git a/tycho-extras-its/src/test/resources/testpomless/targetplatform/targetplatform.target b/tycho-extras-its/src/test/resources/testpomless/targetplatform/targetplatform.target
new file mode 100644
index 0000000..e1218aa
--- /dev/null
+++ b/tycho-extras-its/src/test/resources/testpomless/targetplatform/targetplatform.target
@@ -0,0 +1,10 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<?pde version="3.8"?><target name="Thats my pomless Target" sequenceNumber="1">
+<locations>
+<location includeAllPlatforms="false" includeConfigurePhase="true" includeMode="planner" includeSource="true" type="InstallableUnit">
+<unit id="org.eclipse.equinox.sdk.feature.group" version="3.9.0.v20140221-1852"/>
+<unit id="org.eclipse.jdt.feature.group" version="3.9.2.v20140221-1700"/>
+<repository location="http://download.eclipse.org/releases/kepler/201402280900"/>
+</location>
+</locations>
+</target>
diff --git a/tycho-pomless/src/main/java/org/eclipse/tycho/pomless/AbstractTychoMapping.java b/tycho-pomless/src/main/java/org/eclipse/tycho/pomless/AbstractTychoMapping.java
new file mode 100644
index 0000000..ffb9983
--- /dev/null
+++ b/tycho-pomless/src/main/java/org/eclipse/tycho/pomless/AbstractTychoMapping.java
@@ -0,0 +1,257 @@
+/*******************************************************************************
+ * Copyright (c) 2019 Lablicate GmbH and others.
+ *
+ * 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:
+ * Christoph Läubrich - initial API and implementation,
+ * derived methods setLocation/findParent/getPomVersion from TychoModelReader
+ *******************************************************************************/
+package org.eclipse.tycho.pomless;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.io.Reader;
+import java.io.StringReader;
+import java.nio.charset.Charset;
+import java.nio.charset.StandardCharsets;
+import java.util.HashMap;
+import java.util.Map;
+
+import org.apache.maven.model.InputLocation;
+import org.apache.maven.model.InputSource;
+import org.apache.maven.model.Model;
+import org.apache.maven.model.Parent;
+import org.apache.maven.model.building.ModelProcessor;
+import org.apache.maven.model.io.ModelParseException;
+import org.apache.maven.model.io.ModelReader;
+import org.apache.maven.model.io.ModelWriter;
+import org.codehaus.plexus.PlexusContainer;
+import org.codehaus.plexus.component.annotations.Requirement;
+import org.codehaus.plexus.component.repository.exception.ComponentLookupException;
+import org.codehaus.plexus.logging.Logger;
+import org.sonatype.maven.polyglot.PolyglotModelManager;
+import org.sonatype.maven.polyglot.PolyglotModelUtil;
+import org.sonatype.maven.polyglot.mapping.Mapping;
+
+/**
+ * Base implementation for a {@link Mapping} and {@link ModelReader} that handles all the low-level
+ * stuff, implementations must only handle a small subset
+ *
+ */
+public abstract class AbstractTychoMapping implements Mapping, ModelReader {
+
+ private static final String QUALIFIER_SUFFIX = ".qualifier";
+ private static final String ISSUE_192 = ".takari_issue_192";
+ private static final String MODEL_PARENT = "TychoMapping.model.parent";
+
+ @Requirement
+ protected PlexusContainer container;
+
+ @Requirement
+ protected PolyglotModelManager polyglotModelManager;
+
+ @Requirement
+ protected Logger logger;
+
+ private ModelWriter writer;
+
+ @Override
+ public File locatePom(File dir) {
+ File file = new File(dir, "pom.xml");
+ if (file.exists()) {
+ //we wan't that pom.xml takes precedence over our generated one
+ return null;
+ }
+ File artifact = getPrimaryArtifact(dir);
+ if (artifact != null && artifact.getName().endsWith(".xml")) {
+ File dummyFile = new File(dir, artifact.getName() + ISSUE_192);
+ try {
+ //due to https://github.com/takari/polyglot-maven/issues/192
+ dummyFile.createNewFile();
+ dummyFile.deleteOnExit();
+ return dummyFile;
+ } catch (IOException e) {
+ throw new RuntimeException("creation of replacement file " + dummyFile + " failed", e);
+ }
+ }
+ return artifact;
+ }
+
+ @Override
+ public boolean accept(Map<String, ?> options) {
+ String location = PolyglotModelUtil.getLocation(options);
+ if (location == null || location.endsWith("pom.xml")) {
+ //we wan't that pom.xml takes precedence over our generated one
+ return false;
+ }
+ return isValidLocation(fixLocation(location));
+ }
+
+ private String fixLocation(String location) {
+ if (location != null && location.endsWith(ISSUE_192)) {
+ location = location.substring(0, location.length() - ISSUE_192.length());
+ }
+ return location;
+ }
+
+ @Override
+ public ModelReader getReader() {
+ return this;
+ }
+
+ @Override
+ public ModelWriter getWriter() {
+ if (writer == null) {
+ try {
+ assert container != null;
+ writer = container.lookup(ModelWriter.class, getFlavour());
+ } catch (ComponentLookupException e) {
+ throw new RuntimeException(e);
+ }
+ }
+ return writer;
+ }
+
+ @Override
+ public Model read(InputStream input, Map<String, ?> options) throws IOException, ModelParseException {
+ String location = PolyglotModelUtil.getLocation(options);
+ String fixLocation = fixLocation(location);
+ File file = new File(fixLocation);
+ if (!fixLocation.equals(location)) {
+ //we must use the "fixed" location here until the issue is resolved ignoring the original input stream
+ input = new FileInputStream(file);
+ }
+ return read(new InputStreamReader(input, getPrimaryArtifactCharset()), file, options);
+ }
+
+ @Override
+ public Model read(File input, Map<String, ?> options) throws IOException, ModelParseException {
+ File artifactFile = getRealArtifactFile(input);
+ if (artifactFile.exists()) {
+ try (FileInputStream stream = new FileInputStream(artifactFile)) {
+ return read(new InputStreamReader(stream, getPrimaryArtifactCharset()), input, options);
+ }
+ } else {
+ //we support the case here, that actually there is no real primary artifact, instead of creating a dummy file and forcing I/O we simply simulate to read a 0-byte file
+ return read(new StringReader(""), input, options);
+ }
+ }
+
+ @Override
+ public Model read(Reader input, Map<String, ?> options) throws IOException, ModelParseException {
+ File file = new File(fixLocation(PolyglotModelUtil.getLocation(options)));
+ return read(input, file, options);
+ }
+
+ private Model read(Reader artifactReader, File artifactFile, Map<String, ?> options)
+ throws ModelParseException, IOException {
+ Model model = new Model();
+ model.setModelVersion("4.0.0");
+ model.setPackaging(getPackaging());
+ initModel(model, artifactReader, artifactFile);
+ if (model.getParent() == null) {
+ model.setParent(findParent(artifactFile.getParentFile(), options));
+ }
+ if (model.getVersion() == null) {
+ //inherit version from parent if not given
+ model.setVersion(model.getParent().getVersion());
+ }
+ if (model.getName() == null) {
+ model.setName(model.getArtifactId());
+ }
+ setLocation(model, getRealArtifactFile(artifactFile));
+ return model;
+ }
+
+ protected File getRealArtifactFile(File polyglotArtifactFile) {
+ return polyglotArtifactFile;
+ }
+
+ protected Parent findParent(File projectRoot, Map<String, ?> projectOptions)
+ throws ModelParseException, IOException {
+ Parent parent = (Parent) projectOptions.get(MODEL_PARENT);
+ if (parent != null) {
+ //if the parent is given by the options we don't neet to search it!
+ return parent;
+ }
+
+ // assumption/limitation: parent pom must be physically located in
+ // parent directory
+ File parentPom = polyglotModelManager.locatePom(projectRoot.getParentFile());
+ if (parentPom == null) {
+ throw new FileNotFoundException("No parent pom file found in " + projectRoot.getParentFile());
+ }
+ Map<String, File> options = new HashMap<>(4);
+ options.put(ModelProcessor.SOURCE, parentPom);
+ ModelReader reader = polyglotModelManager.getReaderFor(options);
+ Model parentModel = reader.read(parentPom, options);
+ Parent parentReference = new Parent();
+ String groupId = parentModel.getGroupId();
+ if (groupId == null) {
+ // must be inherited from grandparent
+ groupId = parentModel.getParent().getGroupId();
+ }
+ parentReference.setGroupId(groupId);
+ parentReference.setArtifactId(parentModel.getArtifactId());
+ String version = parentModel.getVersion();
+ if (version == null) {
+ // must be inherited from grandparent
+ version = parentModel.getParent().getVersion();
+ }
+ parentReference.setVersion(version);
+ parentReference.setRelativePath("../" + parentPom.getName());
+ return parentReference;
+ }
+
+ @Override
+ public float getPriority() {
+ return 0;
+ }
+
+ @Override
+ public String getFlavour() {
+ return getPackaging();
+ }
+
+ protected abstract boolean isValidLocation(String location);
+
+ protected abstract File getPrimaryArtifact(File dir);
+
+ protected abstract String getPackaging();
+
+ /**
+ * returns the charset that should be used when reading artifact, default is UTF-8 might be
+ * overridden by subclasses
+ *
+ * @return the charset
+ */
+ protected Charset getPrimaryArtifactCharset() {
+ return StandardCharsets.UTF_8;
+ }
+
+ protected abstract void initModel(Model model, Reader artifactReader, File artifactFile)
+ throws ModelParseException, IOException;
+
+ private static void setLocation(Model model, File modelSource) {
+ InputSource inputSource = new InputSource();
+ inputSource.setLocation(modelSource.toString());
+ inputSource.setModelId(model.getParent().getGroupId() + ":" + model.getArtifactId() + ":" + model.getVersion());
+ model.setLocation("", new InputLocation(0, 0, inputSource));
+ }
+
+ protected static String getPomVersion(String pdeVersion) {
+ String pomVersion = pdeVersion;
+ if (pdeVersion.endsWith(QUALIFIER_SUFFIX)) {
+ pomVersion = pdeVersion.substring(0, pdeVersion.length() - QUALIFIER_SUFFIX.length()) + "-SNAPSHOT";
+ }
+ return pomVersion;
+ }
+}
diff --git a/tycho-pomless/src/main/java/org/eclipse/tycho/pomless/AbstractXMLTychoMapping.java b/tycho-pomless/src/main/java/org/eclipse/tycho/pomless/AbstractXMLTychoMapping.java
new file mode 100644
index 0000000..cadde2c
--- /dev/null
+++ b/tycho-pomless/src/main/java/org/eclipse/tycho/pomless/AbstractXMLTychoMapping.java
@@ -0,0 +1,85 @@
+/*******************************************************************************
+ * Copyright (c) 2019 Lablicate GmbH and others.
+ *
+ * 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:
+ * Christoph Läubrich - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.tycho.pomless;
+
+import java.io.File;
+import java.io.IOException;
+import java.io.Reader;
+
+import javax.xml.parsers.DocumentBuilder;
+import javax.xml.parsers.DocumentBuilderFactory;
+import javax.xml.parsers.ParserConfigurationException;
+
+import org.apache.maven.model.Model;
+import org.apache.maven.model.io.ModelParseException;
+import org.w3c.dom.Attr;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.xml.sax.InputSource;
+import org.xml.sax.SAXException;
+import org.xml.sax.SAXParseException;
+
+/**
+ *
+ * Baseclass for models derived from xml sources
+ */
+public abstract class AbstractXMLTychoMapping extends AbstractTychoMapping {
+
+ private static final DocumentBuilderFactory FACTORY = DocumentBuilderFactory.newInstance();
+
+ @Override
+ protected void initModel(Model model, Reader artifactReader, File artifactFile)
+ throws ModelParseException, IOException {
+ try {
+ DocumentBuilder parser = FACTORY.newDocumentBuilder();
+ Document doc = parser.parse(new InputSource(artifactReader));
+ doc.setDocumentURI(artifactFile.toURI().toASCIIString());
+ Element element = doc.getDocumentElement();
+ initModelFromXML(model, element, artifactFile);
+ } catch (ParserConfigurationException e) {
+ throw new IOException("parser failed", e);
+ } catch (SAXException e) {
+ int lineNumber = -1;
+ int columnNumber = -1;
+ if (e instanceof SAXParseException) {
+ SAXParseException parseException = (SAXParseException) e;
+ lineNumber = parseException.getLineNumber();
+ columnNumber = parseException.getColumnNumber();
+ }
+ throw new ModelParseException(e.getMessage(), lineNumber, columnNumber, e);
+ }
+ }
+
+ protected abstract void initModelFromXML(Model model, Element xml, File artifactFile)
+ throws ModelParseException, IOException;
+
+ protected static String getRequiredXMLAttributeValue(Element element, String attributeName)
+ throws ModelParseException {
+ String value = getXMLAttributeValue(element, attributeName);
+ if (value == null) {
+ throw new ModelParseException(String.format("missing or empty '%s' attribute in element '%s' (uri=%s)",
+ attributeName, element.getNodeName(), element.getOwnerDocument().getDocumentURI()), -1, -1);
+ }
+ return value;
+ }
+
+ protected static String getXMLAttributeValue(Element element, String attributeName) {
+ Attr idNode = element.getAttributeNode(attributeName);
+ if (idNode != null) {
+ String value = idNode.getValue();
+ if (value != null && !value.isEmpty()) {
+ return value;
+ }
+ }
+ return null;
+ }
+}
diff --git a/tycho-pomless/src/main/java/org/eclipse/tycho/pomless/TychoBundleMapping.java b/tycho-pomless/src/main/java/org/eclipse/tycho/pomless/TychoBundleMapping.java
new file mode 100644
index 0000000..ef936c9
--- /dev/null
+++ b/tycho-pomless/src/main/java/org/eclipse/tycho/pomless/TychoBundleMapping.java
@@ -0,0 +1,164 @@
+/*******************************************************************************
+ * Copyright (c) 2019 Lablicate GmbH and others.
+ *
+ * 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:
+ * Christoph Läubrich - initial API and implementation derived from TychoModelReader
+ *******************************************************************************/
+package org.eclipse.tycho.pomless;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.Reader;
+import java.util.Properties;
+import java.util.jar.Attributes;
+import java.util.jar.Manifest;
+
+import org.apache.maven.model.Model;
+import org.apache.maven.model.Organization;
+import org.apache.maven.model.io.ModelParseException;
+import org.codehaus.plexus.component.annotations.Component;
+import org.sonatype.maven.polyglot.mapping.Mapping;
+
+@Component(role = Mapping.class, hint = TychoBundleMapping.PACKAGING)
+public class TychoBundleMapping extends AbstractTychoMapping {
+
+ private static final String BUNDLE_SYMBOLIC_NAME = "Bundle-SymbolicName";
+
+ public static final String PACKAGING = "eclipse-plugin";
+ private static final String PACKAGING_TEST = "eclipse-test-plugin";
+ private static final String MANIFEST_MF = "META-INF/MANIFEST.MF";
+ public static final String MANIFEST_MF_MARKER = ".META-INF_MANIFEST.MF";
+
+ @Override
+ protected boolean isValidLocation(String location) {
+ return location.endsWith(MANIFEST_MF_MARKER);
+ }
+
+ @Override
+ protected File getPrimaryArtifact(File dir) {
+ File manifestFile = new File(dir, MANIFEST_MF);
+ if (manifestFile.isFile()) {
+ File markerFile = new File(dir, MANIFEST_MF_MARKER);
+ try {
+ markerFile.createNewFile();
+ } catch (IOException e) {
+ throw new RuntimeException("can't create markerfile", e);
+ }
+ markerFile.deleteOnExit();
+ return markerFile;
+ }
+ return null;
+ }
+
+ @Override
+ protected String getPackaging() {
+ return PACKAGING;
+ }
+
+ @Override
+ protected void initModel(Model model, Reader artifactReader, File artifactFile)
+ throws ModelParseException, IOException {
+ File manifestFile = new File(artifactFile.getParentFile(), MANIFEST_MF);
+ Attributes manifestHeaders = readManifestHeaders(manifestFile);
+ String bundleSymbolicName = getBundleSymbolicName(manifestHeaders, manifestFile);
+ // groupId is inherited from parent pom
+ model.setArtifactId(bundleSymbolicName);
+ String bundleVersion = getRequiredHeaderValue("Bundle-Version", manifestHeaders, manifestFile);
+ model.setVersion(getPomVersion(bundleVersion));
+ if (isTestBundle(bundleSymbolicName, manifestHeaders)) {
+ model.setPackaging(PACKAGING_TEST);
+ }
+ String bundleName = getManifestAttributeValue(manifestHeaders, "Bundle-Name", manifestFile);
+ if (bundleName != null) {
+ model.setName(bundleName);
+ } else {
+ model.setName(bundleSymbolicName);
+ }
+ String vendorName = getManifestAttributeValue(manifestHeaders, "Bundle-Vendor", manifestFile);
+ if (vendorName != null) {
+ Organization organization = new Organization();
+ organization.setName(vendorName);
+ model.setOrganization(organization);
+ }
+ }
+
+ @Override
+ protected File getRealArtifactFile(File polyglotArtifactFile) {
+ if (polyglotArtifactFile.getName().equals(MANIFEST_MF_MARKER)) {
+ return new File(polyglotArtifactFile.getParentFile(), MANIFEST_MF);
+ }
+ return super.getRealArtifactFile(polyglotArtifactFile);
+ }
+
+ private Attributes readManifestHeaders(File manifestFile) throws IOException {
+ Manifest manifest = new Manifest();
+ try (FileInputStream stream = new FileInputStream(manifestFile)) {
+ manifest.read(stream);
+ }
+ return manifest.getMainAttributes();
+ }
+
+ private String getBundleSymbolicName(Attributes headers, File manifestFile) throws ModelParseException {
+ String symbolicName = getRequiredHeaderValue(BUNDLE_SYMBOLIC_NAME, headers, manifestFile);
+ // strip off any directives/attributes
+ int semicolonIndex = symbolicName.indexOf(';');
+ if (semicolonIndex > 0) {
+ symbolicName = symbolicName.substring(0, semicolonIndex);
+ }
+ return symbolicName;
+ }
+
+ private String getRequiredHeaderValue(String headerKey, Attributes headers, File manifestFile)
+ throws ModelParseException {
+ String value = headers.getValue(headerKey);
+ if (value == null) {
+ throw new ModelParseException("Required header " + headerKey + " missing in " + manifestFile, -1, -1);
+ }
+ return value;
+ }
+
+ private boolean isTestBundle(String bundleSymbolicName, Attributes manifestHeaders) {
+ if (bundleSymbolicName.endsWith(".tests") || bundleSymbolicName.endsWith(".test")) {
+ //TODO can we improve this? maybe also if the import/require bundle contains junit we should assume its a test bundle?
+ // or should we search for Test classes annotations?
+ return true;
+ }
+ return false;
+ }
+
+ private static String getManifestAttributeValue(Attributes headers, String attributeName, File manifestFile)
+ throws IOException {
+ String location = headers.getValue("Bundle-Localization");
+ if (location == null || location.isEmpty()) {
+ location = "OSGI-INF/l10n/bundle.properties";
+ }
+ String rawValue = headers.getValue(attributeName);
+ if (rawValue != null && !rawValue.isEmpty()) {
+ if (rawValue.startsWith("%")) {
+ String key = rawValue.substring(1);
+ //we always use the default here to have consistent build regardless of locale settings
+ File l10nFile = new File(manifestFile.getParentFile().getParentFile(), location);
+ if (l10nFile.exists()) {
+ Properties properties = new Properties();
+ try (InputStream stream = new FileInputStream(l10nFile)) {
+ properties.load(stream);
+ }
+ String translation = properties.getProperty(key);
+ if (translation != null && !translation.isEmpty()) {
+ return translation;
+ }
+ }
+ return key;
+ }
+ }
+ return null;
+ }
+
+}
diff --git a/tycho-pomless/src/main/java/org/eclipse/tycho/pomless/TychoFeatureMapping.java b/tycho-pomless/src/main/java/org/eclipse/tycho/pomless/TychoFeatureMapping.java
new file mode 100644
index 0000000..0b0d87c
--- /dev/null
+++ b/tycho-pomless/src/main/java/org/eclipse/tycho/pomless/TychoFeatureMapping.java
@@ -0,0 +1,66 @@
+/*******************************************************************************
+ * Copyright (c) 2019 Lablicate GmbH and others.
+ *
+ * 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:
+ * Christoph Läubrich - initial API and implementation derived from TychoModelReader
+ *******************************************************************************/
+package org.eclipse.tycho.pomless;
+
+import java.io.File;
+import java.io.IOException;
+
+import org.apache.maven.model.Model;
+import org.apache.maven.model.Organization;
+import org.apache.maven.model.io.ModelParseException;
+import org.codehaus.plexus.component.annotations.Component;
+import org.sonatype.maven.polyglot.mapping.Mapping;
+import org.w3c.dom.Element;
+
+@Component(role = Mapping.class, hint = TychoFeatureMapping.PACKAGING)
+public class TychoFeatureMapping extends AbstractXMLTychoMapping {
+
+ private static final String FEATURE_XML = "feature.xml";
+ public static final String PACKAGING = "eclipse-feature";
+
+ @Override
+ protected void initModelFromXML(Model model, Element xml, File artifactFile)
+ throws ModelParseException, IOException {
+ model.setArtifactId(getRequiredXMLAttributeValue(xml, "id"));
+ model.setVersion(getPomVersion(getRequiredXMLAttributeValue(xml, "version")));
+ String label = getXMLAttributeValue(xml, "label");
+ if (label != null) {
+ model.setName(label);
+ }
+ String provider = getXMLAttributeValue(xml, "provider-name");
+ if (provider != null) {
+ Organization organization = new Organization();
+ organization.setName(provider);
+ model.setOrganization(organization);
+ }
+ }
+
+ @Override
+ protected boolean isValidLocation(String location) {
+ return location.endsWith(FEATURE_XML);
+ }
+
+ @Override
+ protected File getPrimaryArtifact(File dir) {
+ File featureXml = new File(dir, FEATURE_XML);
+ if (featureXml.exists()) {
+ return featureXml;
+ }
+ return null;
+ }
+
+ @Override
+ protected String getPackaging() {
+ return PACKAGING;
+ }
+
+}
diff --git a/tycho-pomless/src/main/java/org/eclipse/tycho/pomless/TychoMapping.java b/tycho-pomless/src/main/java/org/eclipse/tycho/pomless/TychoMapping.java
deleted file mode 100644
index c714a7f..0000000
--- a/tycho-pomless/src/main/java/org/eclipse/tycho/pomless/TychoMapping.java
+++ /dev/null
@@ -1,59 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2015 SAP SE and others.
- * 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:
- * SAP SE - initial API and implementation
- *******************************************************************************/
-package org.eclipse.tycho.pomless;
-
-import java.io.File;
-import java.io.IOException;
-
-import org.codehaus.plexus.component.annotations.Component;
-import org.sonatype.maven.polyglot.mapping.Mapping;
-import org.sonatype.maven.polyglot.mapping.MappingSupport;
-
-@Component(role = Mapping.class, hint = "tycho")
-public class TychoMapping extends MappingSupport {
-
- private static final String ISSUE_192 = ".takari_issue_192";
-
- public TychoMapping() {
- super("tycho");
- // can't check for META-INF/MANIFEST.MF as this is in a subfolder and maven (and tycho) assumes
- // in many places that the pom file is located in the project base dir, so we just use build.properties as a marker file
- setPomNames("build.properties", "category.xml");
- setAcceptLocationExtensions("build.properties", ".product", "category.xml", ISSUE_192);
- // make sure priority is lower than pom.xml (XmlMapping) so we can still override and use pom.xml if needed
- setPriority(-2);
- }
-
- @Override
- public File locatePom(File dir) {
- File pom = super.locatePom(dir);
- if (pom == null) {
- File productFile = TychoModelReader.getProductFile(dir);
- if (productFile != null) {
- return productFile;
- }
- } else {
- if (pom.getName().endsWith(".xml")) {
- File dummyFile = new File(dir, pom.getName() + ISSUE_192);
- try {
- //due to https://github.com/takari/polyglot-maven/issues/192
- dummyFile.createNewFile();
- dummyFile.deleteOnExit();
- return dummyFile;
- } catch (IOException e) {
- throw new RuntimeException("creation of replacement file " + dummyFile + " failed", e);
- }
- }
- }
- return pom;
- }
-
-}
diff --git a/tycho-pomless/src/main/java/org/eclipse/tycho/pomless/TychoModelReader.java b/tycho-pomless/src/main/java/org/eclipse/tycho/pomless/TychoModelReader.java
deleted file mode 100644
index bb75c83..0000000
--- a/tycho-pomless/src/main/java/org/eclipse/tycho/pomless/TychoModelReader.java
+++ /dev/null
@@ -1,358 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2015 SAP SE and others.
- * 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:
- * SAP SE - initial API and implementation
- *******************************************************************************/
-package org.eclipse.tycho.pomless;
-
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.FileNotFoundException;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.Reader;
-import java.util.Arrays;
-import java.util.HashMap;
-import java.util.Map;
-import java.util.Properties;
-import java.util.jar.Attributes;
-import java.util.jar.Manifest;
-
-import javax.xml.parsers.DocumentBuilder;
-import javax.xml.parsers.DocumentBuilderFactory;
-import javax.xml.parsers.ParserConfigurationException;
-
-import org.apache.maven.model.Build;
-import org.apache.maven.model.InputLocation;
-import org.apache.maven.model.InputSource;
-import org.apache.maven.model.Model;
-import org.apache.maven.model.Organization;
-import org.apache.maven.model.Parent;
-import org.apache.maven.model.Plugin;
-import org.apache.maven.model.PluginExecution;
-import org.apache.maven.model.building.ModelProcessor;
-import org.apache.maven.model.io.ModelParseException;
-import org.apache.maven.model.io.ModelReader;
-import org.codehaus.plexus.component.annotations.Component;
-import org.codehaus.plexus.component.annotations.Requirement;
-import org.codehaus.plexus.util.xml.Xpp3Dom;
-import org.sonatype.maven.polyglot.PolyglotModelManager;
-import org.sonatype.maven.polyglot.PolyglotModelUtil;
-import org.sonatype.maven.polyglot.io.ModelReaderSupport;
-import org.w3c.dom.Attr;
-import org.w3c.dom.Document;
-import org.w3c.dom.Element;
-import org.xml.sax.SAXException;
-
-/**
- * Tycho POM model reader. Deduces maven model artifactId and version from OSGi manifest
- * Bundle-SymbolicName and Bundle-Version headers or feature.xml id and version attributes. Assumes
- * parent pom is located in parent directory (from which groupId is inherited). Bundles with
- * Bundle-SymbolicName ending with ".tests" will be assigned packaging type "eclipse-test-plugin".
- */
-@Component(role = ModelReader.class, hint = "tycho")
-public class TychoModelReader extends ModelReaderSupport {
-
- private static final String UPDATE_SITE_SUFFIX = ".eclipse-repository";
- private static final String BUNDLE_SYMBOLIC_NAME = "Bundle-SymbolicName";
- private static final String QUALIFIER_SUFFIX = ".qualifier";
-
- @Requirement
- private PolyglotModelManager polyglotModelManager;
-
- public TychoModelReader() {
- }
-
- @Override
- public Model read(Reader input, Map<String, ?> options) throws IOException, ModelParseException {
- File projectRoot = new File(PolyglotModelUtil.getLocation(options)).getParentFile();
- File manifestFile = new File(projectRoot, "META-INF/MANIFEST.MF");
- File featureXml = new File(projectRoot, "feature.xml");
- File categoryXml = new File(projectRoot, "category.xml");
- File productXml = getProductFile(projectRoot);
- if (manifestFile.isFile()) {
- return createPomFromManifest(manifestFile);
- } else if (featureXml.isFile()) {
- return createPomFromFeatureXml(featureXml);
- } else if (productXml != null) {
- return createPomFromProductXml(productXml);
- } else if (categoryXml.isFile()) {
- return createPomFromCategoryXml(categoryXml);
- } else {
- throw new IOException("Neither META-INF/MANIFEST.MF, feature.xml, .product nor category.xml file found in "
- + projectRoot);
- }
- }
-
- private Model createPomFromManifest(File manifestFile) throws IOException, ModelParseException {
- Attributes headers = readManifestHeaders(manifestFile);
- String bundleSymbolicName = getBundleSymbolicName(headers, manifestFile);
- Model model = createModel();
- model.setParent(findParent(manifestFile.getParentFile().getParentFile()));
- // groupId is inherited from parent pom
- model.setArtifactId(bundleSymbolicName);
- String bundleVersion = getRequiredHeaderValue("Bundle-Version", headers, manifestFile);
- model.setVersion(getPomVersion(bundleVersion));
- model.setPackaging(getPackagingType(bundleSymbolicName));
- setLocation(model, manifestFile);
- String bundleName = getManifestAttributeValue(headers, "Bundle-Name", manifestFile);
- if (bundleName != null) {
- model.setName(bundleName);
- } else {
- model.setName(bundleSymbolicName);
- }
- String vendorName = getManifestAttributeValue(headers, "Bundle-Vendor", manifestFile);
- if (vendorName != null) {
- Organization organization = new Organization();
- organization.setName(vendorName);
- model.setOrganization(organization);
- }
- return model;
- }
-
- private static String getManifestAttributeValue(Attributes headers, String attributeName, File manifestFile)
- throws IOException {
- String location = headers.getValue("Bundle-Localization");
- if (location == null || location.isEmpty()) {
- location = "OSGI-INF/l10n/bundle.properties";
- }
- String rawValue = headers.getValue(attributeName);
- if (rawValue != null && !rawValue.isEmpty()) {
- if (rawValue.startsWith("%")) {
- String key = rawValue.substring(1);
- //we always use the default here to have consistent build regardless of locale settings
- File l10nFile = new File(manifestFile.getParentFile().getParentFile(), location);
- if (l10nFile.exists()) {
- Properties properties = new Properties();
- try (InputStream stream = new FileInputStream(l10nFile)) {
- properties.load(stream);
- }
- String translation = properties.getProperty(key);
- if (translation != null && !translation.isEmpty()) {
- return translation;
- }
- }
- return key;
- }
- }
- return null;
- }
-
- private Model createPomFromFeatureXml(File featureXml) throws IOException, ModelParseException {
- Model model = createPomFromXmlFile(featureXml, "id", "version", "label", "provider-name");
- model.setPackaging("eclipse-feature");
- return model;
- }
-
- private Model createPomFromProductXml(File productXml) throws IOException, ModelParseException {
- Model model = createPomFromXmlFile(productXml, "uid", "version", "name", null);
- model.setPackaging("eclipse-repository");
-
- Build build = new Build();
- Plugin plugin = new Plugin();
- build.addPlugin(plugin);
- plugin.setArtifactId("tycho-p2-director-plugin");
- plugin.setGroupId("org.eclipse.tycho");
-
- PluginExecution materialize = new PluginExecution();
- materialize.setId("materialize-prodcuts");
- materialize.setGoals(Arrays.asList("materialize-products"));
- plugin.addExecution(materialize);
- Xpp3Dom config = new Xpp3Dom("configuration");
- Xpp3Dom products = new Xpp3Dom("products");
- Xpp3Dom product = new Xpp3Dom("product");
- Xpp3Dom id = new Xpp3Dom("id");
- id.setValue(model.getArtifactId());
- config.addChild(products);
- products.addChild(product);
- product.addChild(id);
- materialize.setConfiguration(config);
- PluginExecution archive = new PluginExecution();
- archive.setId("archive-prodcuts");
- archive.setGoals(Arrays.asList("archive-products"));
- archive.setConfiguration(config);
- plugin.addExecution(archive);
-
- model.setBuild(build);
- return model;
- }
-
- private Model createPomFromXmlFile(File xmlFile, String idAttributeName, String versionAttributeName,
- String nameAttributeName, String vendorAttributeName) throws IOException, ModelParseException {
- Element root = getRootXmlElement(xmlFile);
- Model model = createModel();
- model.setParent(findParent(xmlFile.getParentFile()));
- String id = getXMLAttributeValue(root, idAttributeName);
- if (id == null) {
- throw new ModelParseException(String.format("missing or empty %s attribute in root element (%s)",
- idAttributeName, xmlFile.getAbsolutePath()), -1, -1);
- }
- model.setArtifactId(id);
- model.setName(id);
- String version = getXMLAttributeValue(root, versionAttributeName);
- if (version == null) {
- throw new ModelParseException(String.format("missing or empty %s attribute in root element (%s)",
- versionAttributeName, xmlFile.getAbsolutePath()), -1, -1);
- }
- model.setVersion(getPomVersion(version));
- if (nameAttributeName != null) {
- String name = getXMLAttributeValue(root, nameAttributeName);
- if (name != null) {
- model.setName(name);
- }
- }
- if (vendorAttributeName != null) {
- String vendor = getXMLAttributeValue(root, vendorAttributeName);
- if (vendor != null) {
- Organization organization = new Organization();
- organization.setName(vendor);
- model.setOrganization(organization);
- }
- }
- // groupId is inherited from parent pom
- setLocation(model, xmlFile);
- return model;
- }
-
- private static String getXMLAttributeValue(Element element, String attributeName) {
- Attr idNode = element.getAttributeNode(attributeName);
- if (idNode != null) {
- String value = idNode.getValue();
- if (value != null && !value.isEmpty()) {
- return value;
- }
- }
- return null;
- }
-
- private Model createPomFromCategoryXml(File categoryXml) throws ModelParseException, IOException {
- Model model = createModel();
- model.setPackaging("eclipse-repository");
- Parent parent = findParent(categoryXml.getParentFile());
- model.setParent(parent);
- String name = categoryXml.getParentFile().getName();
- if (!name.endsWith(UPDATE_SITE_SUFFIX)) {
- name = name + UPDATE_SITE_SUFFIX;
- }
- String prefix = parent.getArtifactId() + ".";
- if (!name.startsWith(prefix)) {
- name = prefix + name;
- }
- model.setArtifactId(name);
- model.setName(name);
- model.setVersion(parent.getVersion());
- return model;
- }
-
- private Element getRootXmlElement(File xmlFile) throws IOException, ModelParseException {
- Document doc;
- try {
- DocumentBuilder parser = DocumentBuilderFactory.newInstance().newDocumentBuilder();
- doc = parser.parse(xmlFile);
- } catch (ParserConfigurationException e) {
- throw new RuntimeException(e);
- } catch (SAXException e) {
- throw new ModelParseException(e.getMessage(), -1, -1);
- }
- return doc.getDocumentElement();
- }
-
- private Model createModel() {
- Model model = new Model();
- model.setModelVersion("4.0.0");
- return model;
- }
-
- private String getBundleSymbolicName(Attributes headers, File manifestFile) throws ModelParseException {
- String symbolicName = getRequiredHeaderValue(BUNDLE_SYMBOLIC_NAME, headers, manifestFile);
- // strip off any directives/attributes
- int semicolonIndex = symbolicName.indexOf(';');
- if (semicolonIndex > 0) {
- symbolicName = symbolicName.substring(0, semicolonIndex);
- }
- return symbolicName;
- }
-
- private String getRequiredHeaderValue(String headerKey, Attributes headers, File manifestFile)
- throws ModelParseException {
- String value = headers.getValue(headerKey);
- if (value == null) {
- throw new ModelParseException("Required header " + headerKey + " missing in " + manifestFile, -1, -1);
- }
- return value;
- }
-
- private Attributes readManifestHeaders(File manifestFile) throws IOException {
- Manifest manifest = new Manifest();
- try (FileInputStream stream = new FileInputStream(manifestFile)) {
- manifest.read(stream);
- }
- return manifest.getMainAttributes();
- }
-
- private static String getPomVersion(String pdeVersion) {
- String pomVersion = pdeVersion;
- if (pdeVersion.endsWith(QUALIFIER_SUFFIX)) {
- pomVersion = pdeVersion.substring(0, pdeVersion.length() - QUALIFIER_SUFFIX.length()) + "-SNAPSHOT";
- }
- return pomVersion;
- }
-
- private String getPackagingType(String symbolicName) {
- // assume test bundles end with ".tests"
- if (symbolicName.endsWith(".tests")) {
- return "eclipse-test-plugin";
- } else {
- return "eclipse-plugin";
- }
- }
-
- public static File getProductFile(File projectRoot) {
- File[] productFiles = projectRoot
- .listFiles((File dir, String name) -> name.endsWith(".product") && !name.startsWith(".polyglot"));
- if (productFiles.length > 0 && productFiles[0].isFile()) {
- return productFiles[0];
- }
- return null;
- }
-
- Parent findParent(File projectRoot) throws ModelParseException, IOException {
- // assumption/limitation: parent pom must be physically located in
- // parent directory
- File parentPom = polyglotModelManager.locatePom(projectRoot.getParentFile());
- if (parentPom == null) {
- throw new FileNotFoundException("No parent pom file found in " + projectRoot.getParentFile());
- }
- Map<String, File> options = new HashMap<>(4);
- options.put(ModelProcessor.SOURCE, parentPom);
- ModelReader reader = polyglotModelManager.getReaderFor(options);
- Model parentModel = reader.read(parentPom, options);
- Parent parentReference = new Parent();
- String groupId = parentModel.getGroupId();
- if (groupId == null) {
- // must be inherited from grandparent
- groupId = parentModel.getParent().getGroupId();
- }
- parentReference.setGroupId(groupId);
- parentReference.setArtifactId(parentModel.getArtifactId());
- String version = parentModel.getVersion();
- if (version == null) {
- // must be inherited from grandparent
- version = parentModel.getParent().getVersion();
- }
- parentReference.setVersion(version);
- return parentReference;
- }
-
- private void setLocation(Model model, File modelSource) {
- InputSource inputSource = new InputSource();
- inputSource.setLocation(modelSource.toString());
- inputSource.setModelId(model.getParent().getGroupId() + ":" + model.getArtifactId() + ":" + model.getVersion());
- model.setLocation("", new InputLocation(0, 0, inputSource));
- }
-}
diff --git a/tycho-pomless/src/main/java/org/eclipse/tycho/pomless/TychoRepositoryMapping.java b/tycho-pomless/src/main/java/org/eclipse/tycho/pomless/TychoRepositoryMapping.java
new file mode 100644
index 0000000..d3743f8
--- /dev/null
+++ b/tycho-pomless/src/main/java/org/eclipse/tycho/pomless/TychoRepositoryMapping.java
@@ -0,0 +1,126 @@
+/*******************************************************************************
+ * Copyright (c) 2019 Lablicate GmbH and others.
+ *
+ * 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:
+ * Christoph Läubrich - initial API and implementation derived from TychoModelReader
+ *******************************************************************************/
+package org.eclipse.tycho.pomless;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.Arrays;
+
+import org.apache.maven.model.Build;
+import org.apache.maven.model.Model;
+import org.apache.maven.model.Plugin;
+import org.apache.maven.model.PluginExecution;
+import org.apache.maven.model.io.ModelParseException;
+import org.codehaus.plexus.component.annotations.Component;
+import org.codehaus.plexus.util.xml.Xpp3Dom;
+import org.sonatype.maven.polyglot.mapping.Mapping;
+import org.w3c.dom.Element;
+
+/**
+ *
+ * Responsible for parsing eclipse-repository artifacts (updatesites, catgory.xml)
+ */
+@Component(role = Mapping.class, hint = TychoRepositoryMapping.PACKAGING)
+public class TychoRepositoryMapping extends AbstractXMLTychoMapping {
+ private static final String CATEGORY_XML = "category.xml";
+ private static final String PRODUCT_EXTENSION = ".product";
+ public static final String PACKAGING = "eclipse-repository";
+ private static final String UPDATE_SITE_SUFFIX = "." + PACKAGING;
+
+ @Override
+ protected String getPackaging() {
+ return PACKAGING;
+ }
+
+ @Override
+ protected void initModelFromXML(Model model, Element xml, File artifactFile)
+ throws ModelParseException, IOException {
+ if (artifactFile.getName().endsWith(PRODUCT_EXTENSION)) {
+ initFromProdcut(model, xml);
+ } else {
+ initFromCategory(model, xml, artifactFile);
+ }
+ }
+
+ private void initFromCategory(Model model, Element xml, File categoryXml) {
+ String name = categoryXml.getParentFile().getName();
+ if (!name.endsWith(UPDATE_SITE_SUFFIX)) {
+ name = name + UPDATE_SITE_SUFFIX;
+ }
+ model.setArtifactId(name);
+ model.setName(name);
+ }
+
+ private void initFromProdcut(Model model, Element xml) throws ModelParseException {
+ model.setArtifactId(getRequiredXMLAttributeValue(xml, "uid"));
+ String version = getXMLAttributeValue(xml, "version");
+ if (version != null) {
+ model.setVersion(getPomVersion(version));
+ }
+ String name = getXMLAttributeValue(xml, "name");
+ if (name != null) {
+ model.setName(name);
+ }
+
+ Build build = new Build();
+ Plugin plugin = new Plugin();
+ build.addPlugin(plugin);
+ plugin.setArtifactId("tycho-p2-director-plugin");
+ plugin.setGroupId("org.eclipse.tycho");
+
+ PluginExecution materialize = new PluginExecution();
+ materialize.setId("materialize-prodcuts");
+ materialize.setGoals(Arrays.asList("materialize-products"));
+ plugin.addExecution(materialize);
+ Xpp3Dom config = new Xpp3Dom("configuration");
+ Xpp3Dom products = new Xpp3Dom("products");
+ Xpp3Dom product = new Xpp3Dom("product");
+ Xpp3Dom id = new Xpp3Dom("id");
+ id.setValue(model.getArtifactId());
+ config.addChild(products);
+ products.addChild(product);
+ product.addChild(id);
+ materialize.setConfiguration(config);
+ PluginExecution archive = new PluginExecution();
+ archive.setId("archive-prodcuts");
+ archive.setGoals(Arrays.asList("archive-products"));
+ archive.setConfiguration(config);
+ plugin.addExecution(archive);
+
+ model.setBuild(build);
+
+ }
+
+ @Override
+ protected boolean isValidLocation(String location) {
+ return location.endsWith(PRODUCT_EXTENSION) || location.endsWith(CATEGORY_XML);
+ }
+
+ @Override
+ protected File getPrimaryArtifact(File projectRoot) {
+ File[] productFiles = projectRoot.listFiles(
+ (File dir, String name) -> name.endsWith(PRODUCT_EXTENSION) && !name.startsWith(".polyglot"));
+ if (productFiles != null && productFiles.length > 0) {
+ for (File file : productFiles) {
+ if (file.isFile()) {
+ return file;
+ }
+ }
+ }
+ File category = new File(projectRoot, CATEGORY_XML);
+ if (category.exists()) {
+ return category;
+ }
+ return null;
+ }
+
+}
diff --git a/tycho-pomless/src/main/java/org/eclipse/tycho/pomless/TychoTargetMapping.java b/tycho-pomless/src/main/java/org/eclipse/tycho/pomless/TychoTargetMapping.java
new file mode 100644
index 0000000..ec8822a
--- /dev/null
+++ b/tycho-pomless/src/main/java/org/eclipse/tycho/pomless/TychoTargetMapping.java
@@ -0,0 +1,79 @@
+/*******************************************************************************
+ * Copyright (c) 2019 Lablicate GmbH and others.
+ *
+ * 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:
+ * Christoph Läubrich - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.tycho.pomless;
+
+import java.io.File;
+import java.io.FileFilter;
+import java.io.IOException;
+
+import org.apache.maven.model.Model;
+import org.apache.maven.model.io.ModelParseException;
+import org.codehaus.plexus.component.annotations.Component;
+import org.sonatype.maven.polyglot.mapping.Mapping;
+import org.w3c.dom.Element;
+
+@Component(role = Mapping.class, hint = TychoTargetMapping.PACKAGING)
+public class TychoTargetMapping extends AbstractXMLTychoMapping {
+
+ private static final String TARGET_EXTENSION = ".target";
+ public static final String PACKAGING = "eclipse-target-definition";
+
+ @Override
+ protected String getPackaging() {
+ return PACKAGING;
+ }
+
+ @Override
+ protected boolean isValidLocation(String location) {
+ return location.endsWith(TARGET_EXTENSION);
+ }
+
+ @Override
+ protected File getPrimaryArtifact(File dir) {
+ File file = new File(dir, dir.getName() + TARGET_EXTENSION);
+ if (file.exists()) {
+ return file;
+ }
+ File[] listFiles = dir.listFiles(new FileFilter() {
+
+ @Override
+ public boolean accept(File file) {
+ return file.isFile() && file.getName().endsWith(TARGET_EXTENSION);
+ }
+ });
+ if (listFiles != null && listFiles.length > 0) {
+ if (listFiles.length == 1) {
+ return listFiles[0];
+ } else {
+ throw new IllegalArgumentException("only one " + TARGET_EXTENSION
+ + " file is allowed per target project, or target must be named like the folder (<foldername>"
+ + TARGET_EXTENSION + ")");
+ }
+ }
+ return null;
+ }
+
+ @Override
+ protected void initModelFromXML(Model model, Element xml, File artifactFile)
+ throws ModelParseException, IOException {
+ String fileName = artifactFile.getName();
+ String artifactId = fileName.substring(0, fileName.length() - TARGET_EXTENSION.length());
+ model.setArtifactId(artifactId);
+ String name = getXMLAttributeValue(xml, "name");
+ if (name != null) {
+ model.setName(name);
+ } else {
+ model.setName(artifactId);
+ }
+ }
+
+}
diff --git a/tycho-pomless/src/test/java/org/eclipse/tycho/pomless/TychoMappingTest.java b/tycho-pomless/src/test/java/org/eclipse/tycho/pomless/TychoMappingTest.java
index 9cc5007..910150c 100644
--- a/tycho-pomless/src/test/java/org/eclipse/tycho/pomless/TychoMappingTest.java
+++ b/tycho-pomless/src/test/java/org/eclipse/tycho/pomless/TychoMappingTest.java
@@ -26,11 +26,13 @@ public class TychoMappingTest extends PlexusTestCase {
public void testLocateBuildProperties() throws Exception {
File pom = polyglotModelManager.locatePom(new File(getMappingTestDir(), "simple"));
- assertEquals("build.properties", pom.getName());
+ assertNotNull(pom);
+ assertEquals(TychoBundleMapping.MANIFEST_MF_MARKER, pom.getName());
}
public void testPriority() throws Exception {
File pom = polyglotModelManager.locatePom(new File(getMappingTestDir(), "precedence"));
+ assertNotNull(pom);
assertEquals("pom.xml must win over build.properties", "pom.xml", pom.getName());
}
diff --git a/tycho-pomless/src/test/java/org/eclipse/tycho/pomless/TychoModelReaderTest.java b/tycho-pomless/src/test/java/org/eclipse/tycho/pomless/TychoModelReaderTest.java
index 69d5f0c..0c220de 100644
--- a/tycho-pomless/src/test/java/org/eclipse/tycho/pomless/TychoModelReaderTest.java
+++ b/tycho-pomless/src/test/java/org/eclipse/tycho/pomless/TychoModelReaderTest.java
@@ -15,7 +15,6 @@ import static org.junit.Assert.assertThat;
import java.io.File;
import java.io.IOException;
-import java.io.Reader;
import java.util.HashMap;
import java.util.Map;
@@ -27,21 +26,17 @@ import org.apache.maven.model.building.ModelProcessor;
import org.apache.maven.model.io.ModelParseException;
import org.apache.maven.model.io.ModelReader;
import org.codehaus.plexus.PlexusTestCase;
+import org.codehaus.plexus.component.repository.exception.ComponentLookupException;
import org.junit.Test;
+import org.sonatype.maven.polyglot.mapping.Mapping;
public class TychoModelReaderTest extends PlexusTestCase {
- private TychoModelReader tychoModelReader;
-
- @Override
- protected void setUp() throws Exception {
- tychoModelReader = (TychoModelReader) lookup(ModelReader.class, "tycho");
- }
-
@Test
public void testReadBundle() throws Exception {
- File buildProperties = new File(getPolyglotTestDir(), "bundle1/build.properties");
- Model model = tychoModelReader.read((Reader) null, createReaderOptions(buildProperties));
+ File buildProperties = new File(getPolyglotTestDir(), "bundle1/" + TychoBundleMapping.MANIFEST_MF_MARKER);
+ Model model = getTychoModelReader(TychoBundleMapping.PACKAGING).read(buildProperties,
+ createReaderOptions(buildProperties));
assertEquals("4.0.0", model.getModelVersion());
assertEquals("pomless.bundle", model.getArtifactId());
assertEquals("0.1.0-SNAPSHOT", model.getVersion());
@@ -52,8 +47,9 @@ public class TychoModelReaderTest extends PlexusTestCase {
@Test
public void testReadTestBundle() throws Exception {
- File buildProperties = new File(getPolyglotTestDir(), "bundle1.tests/build.properties");
- Model model = tychoModelReader.read((Reader) null, createReaderOptions(buildProperties));
+ File buildProperties = new File(getPolyglotTestDir(), "bundle1.tests/" + TychoBundleMapping.MANIFEST_MF_MARKER);
+ Model model = getTychoModelReader(TychoBundleMapping.PACKAGING).read(buildProperties,
+ createReaderOptions(buildProperties));
assertEquals("pomless.bundle.tests", model.getArtifactId());
assertEquals("1.0.1", model.getVersion());
assertEquals("eclipse-test-plugin", model.getPackaging());
@@ -63,8 +59,8 @@ public class TychoModelReaderTest extends PlexusTestCase {
@Test
public void testReadFeature() throws Exception {
- File buildProperties = new File(getPolyglotTestDir(), "feature/build.properties");
- Model model = tychoModelReader.read((Reader) null, createReaderOptions(buildProperties));
+ File feature = new File(getPolyglotTestDir(), "feature/feature.xml");
+ Model model = getTychoModelReader(TychoFeatureMapping.PACKAGING).read(feature, createReaderOptions(feature));
assertEquals("pomless.feature", model.getArtifactId());
assertEquals("1.0.0-SNAPSHOT", model.getVersion());
assertEquals("eclipse-feature", model.getPackaging());
@@ -74,20 +70,18 @@ public class TychoModelReaderTest extends PlexusTestCase {
@Test
public void testMissingManifestOrFeature() throws Exception {
- File buildProperties = new File(getTestResourcesDir(), "modelreader/missingManifestOrFeature/build.properties");
- try {
- tychoModelReader.read((Reader) null, createReaderOptions(buildProperties));
- fail();
- } catch (IOException e) {
- // expected
- }
+ File buildDir = new File(getTestResourcesDir(), "modelreader/missingManifestOrFeature/");
+ assertNull(getMapping(TychoBundleMapping.PACKAGING).locatePom(buildDir));
+ assertNull(getMapping(TychoFeatureMapping.PACKAGING).locatePom(buildDir));
+ assertNull(getMapping(TychoRepositoryMapping.PACKAGING).locatePom(buildDir));
+ assertNull(getMapping(TychoTargetMapping.PACKAGING).locatePom(buildDir));
}
@Test
public void testIllFormedFeature() throws Exception {
- File buildProperties = new File(getTestResourcesDir(), "modelreader/features/illFormed/build.properties");
+ File featureXml = new File(getTestResourcesDir(), "modelreader/features/illFormed/feature.xml");
try {
- tychoModelReader.read((Reader) null, createReaderOptions(buildProperties));
+ getTychoModelReader(TychoFeatureMapping.PACKAGING).read(featureXml, createReaderOptions(featureXml));
fail();
} catch (ModelParseException e) {
// expected
@@ -96,31 +90,33 @@ public class TychoModelReaderTest extends PlexusTestCase {
@Test
public void testFeatureWithoutId() throws Exception {
- File buildProperties = new File(getTestResourcesDir(), "modelreader/features/missingId/build.properties");
+ File featureXml = new File(getTestResourcesDir(), "modelreader/features/missingId/feature.xml");
try {
- tychoModelReader.read((Reader) null, createReaderOptions(buildProperties));
+ getTychoModelReader(TychoFeatureMapping.PACKAGING).read(featureXml, createReaderOptions(featureXml));
fail();
} catch (ModelParseException e) {
- assertThat(e.getMessage(), containsString("missing or empty id attribute in root element"));
+ assertThat(e.getMessage(), containsString("missing or empty 'id' attribute in element 'feature'"));
}
}
@Test
public void testFeatureWithoutVersion() throws Exception {
- File buildProperties = new File(getTestResourcesDir(), "modelreader/features/missingVersion/build.properties");
+ File featureXml = new File(getTestResourcesDir(), "modelreader/features/missingVersion/feature.xml");
try {
- tychoModelReader.read((Reader) null, createReaderOptions(buildProperties));
+ getTychoModelReader(TychoFeatureMapping.PACKAGING).read(featureXml, createReaderOptions(featureXml));
fail();
} catch (ModelParseException e) {
- assertThat(e.getMessage(), containsString("missing or empty version attribute in root element"));
+ assertThat(e.getMessage(), containsString("missing or empty 'version' attribute in element 'feature'"));
}
}
@Test
public void testBundleWithoutSymbolicName() throws Exception {
- File buildProperties = new File(getTestResourcesDir(), "modelreader/plugins/missingBsn/build.properties");
+ File buildProperties = new File(getTestResourcesDir(),
+ "modelreader/plugins/missingBsn/" + TychoBundleMapping.MANIFEST_MF_MARKER);
try {
- tychoModelReader.read((Reader) null, createReaderOptions(buildProperties));
+ getTychoModelReader(TychoBundleMapping.PACKAGING).read(buildProperties,
+ createReaderOptions(buildProperties));
fail();
} catch (ModelParseException e) {
assertThat(e.getMessage(), containsString("Bundle-SymbolicName missing in"));
@@ -129,9 +125,11 @@ public class TychoModelReaderTest extends PlexusTestCase {
@Test
public void testBundleWithoutVersion() throws Exception {
- File buildProperties = new File(getTestResourcesDir(), "modelreader/plugins/missingVersion/build.properties");
+ File buildProperties = new File(getTestResourcesDir(),
+ "modelreader/plugins/missingVersion/" + TychoBundleMapping.MANIFEST_MF_MARKER);
try {
- tychoModelReader.read((Reader) null, createReaderOptions(buildProperties));
+ getTychoModelReader(TychoBundleMapping.PACKAGING).read(buildProperties,
+ createReaderOptions(buildProperties));
fail();
} catch (ModelParseException e) {
assertThat(e.getMessage(), containsString("Bundle-Version missing in"));
@@ -140,9 +138,11 @@ public class TychoModelReaderTest extends PlexusTestCase {
@Test
public void testNoParent() throws Exception {
- File buildProperties = new File(getTestResourcesDir(), "modelreader/noParent/bundle/build.properties");
+ File buildProperties = new File(getTestResourcesDir(),
+ "modelreader/noParent/bundle/" + TychoBundleMapping.MANIFEST_MF_MARKER);
try {
- tychoModelReader.read((Reader) null, createReaderOptions(buildProperties));
+ getTychoModelReader(TychoBundleMapping.PACKAGING).read(buildProperties,
+ createReaderOptions(buildProperties));
fail();
} catch (IOException e) {
assertThat(e.getMessage(), containsString("No parent pom file found in"));
@@ -151,17 +151,20 @@ public class TychoModelReaderTest extends PlexusTestCase {
@Test
public void testFindParent() throws Exception {
- Parent parentReference = tychoModelReader
- .findParent(new File(getTestResourcesDir(), "modelreader/grandparentInheritance/bundle/"));
+ File location = new File(getTestResourcesDir(),
+ "modelreader/grandparentInheritance/bundle/" + TychoBundleMapping.MANIFEST_MF_MARKER);
+ Model model = getTychoModelReader(TychoBundleMapping.PACKAGING).read(location, createReaderOptions(location));
+ assertNotNull(model);
+ Parent parentReference = model.getParent();
assertEquals("bundle-parent", parentReference.getArtifactId());
assertEquals("grandparent.groupid", parentReference.getGroupId());
assertEquals("1.2.3", parentReference.getVersion());
}
@Test
- public void testReadProduct() throws ModelParseException, IOException {
- File buildProperties = new File(getPolyglotTestDir(), "product/build.properties");
- Model model = tychoModelReader.read((Reader) null, createReaderOptions(buildProperties));
+ public void testReadProduct() throws ModelParseException, IOException, ComponentLookupException {
+ File product = new File(getPolyglotTestDir(), "product/myproduct.product");
+ Model model = getTychoModelReader(TychoRepositoryMapping.PACKAGING).read(product, createReaderOptions(product));
assertEquals("4.0.0", model.getModelVersion());
assertEquals("pomless.product.validproduct", model.getArtifactId());
assertEquals("0.0.2-SNAPSHOT", model.getVersion());
@@ -169,45 +172,49 @@ public class TychoModelReaderTest extends PlexusTestCase {
assertParent(model.getParent());
}
- @Test
- public void testProductWithoutUid() throws IOException {
- File buildProperties = new File(getTestResourcesDir(), "modelreader/products/missingUid/build.properties");
- try {
- tychoModelReader.read((Reader) null, createReaderOptions(buildProperties));
- fail();
- } catch (ModelParseException e) {
- assertThat(e.getMessage(), containsString("missing or empty uid attribute"));
- }
+ public ModelReader getTychoModelReader(String packaging) throws ComponentLookupException {
+ return getMapping(packaging).getReader();
+ }
+
+ private Mapping getMapping(String packaging) throws ComponentLookupException {
+ return lookup(Mapping.class, packaging);
}
@Test
- public void testProductWithoutVersion() throws IOException {
- File buildProperties = new File(getTestResourcesDir(), "modelreader/products/missingVersion/build.properties");
+ public void testProductWithoutUid() throws IOException, ComponentLookupException {
try {
- tychoModelReader.read((Reader) null, createReaderOptions(buildProperties));
+ File product = new File(getTestResourcesDir(), "modelreader/products/missingUid/myproduct.product");
+ getTychoModelReader(TychoRepositoryMapping.PACKAGING).read(product, createReaderOptions(product));
fail();
} catch (ModelParseException e) {
- assertThat(e.getMessage(), containsString("missing or empty version attribute"));
+ assertThat(e.getMessage(), containsString("missing or empty 'uid' attribute in element 'product'"));
}
}
@Test
+ public void testProductWithoutVersion() throws IOException, ComponentLookupException {
+ File product = new File(getTestResourcesDir(), "modelreader/products/missingVersion/myproduct.product");
+ getTychoModelReader(TychoRepositoryMapping.PACKAGING).read(product, createReaderOptions(product));
+ }
+
+ @Test()
public void testIllFormedProduct() throws Exception {
- File buildProperties = new File(getTestResourcesDir(), "modelreader/products/illFormed/build.properties");
+ File product = new File(getTestResourcesDir(), "modelreader/products/illFormed/myproduct.product");
try {
- tychoModelReader.read((Reader) null, createReaderOptions(buildProperties));
+ getTychoModelReader(TychoRepositoryMapping.PACKAGING).read(product, createReaderOptions(product));
fail();
} catch (ModelParseException e) {
- // expected
+ //expected
}
}
@Test
- public void testReadUpdateSite() throws ModelParseException, IOException {
- File buildProperties = new File(getPolyglotTestDir(), "updatesite/build.properties");
- Model model = tychoModelReader.read((Reader) null, createReaderOptions(buildProperties));
+ public void testReadUpdateSite() throws ModelParseException, IOException, ComponentLookupException {
+ File updatesite = new File(getTestResourcesDir(), "modelreader/updatesites/site/category.xml");
+ Model model = getTychoModelReader(TychoRepositoryMapping.PACKAGING).read(updatesite,
+ createReaderOptions(updatesite));
assertEquals("4.0.0", model.getModelVersion());
- assertEquals("testparent.updatesite.eclipse-repository", model.getArtifactId());
+ assertEquals("site.eclipse-repository", model.getArtifactId());
assertEquals("0.0.1-SNAPSHOT", model.getVersion());
assertEquals("eclipse-repository", model.getPackaging());
assertParent(model.getParent());
diff --git a/tycho-pomless/src/test/resources/mapping/precedence/META-INF/MANIFEST.MF b/tycho-pomless/src/test/resources/mapping/precedence/META-INF/MANIFEST.MF
new file mode 100644
index 0000000..dd76591
--- /dev/null
+++ b/tycho-pomless/src/test/resources/mapping/precedence/META-INF/MANIFEST.MF
@@ -0,0 +1,6 @@
+Manifest-Version: 1.0
+Bundle-ManifestVersion: 2
+Missing-Bundle-SymbolicName: pomless.bundle;singleton:=true
+Bundle-Version: 0.1.0.qualifier
+Bundle-SymbolicName: precedence
+
diff --git a/tycho-pomless/src/test/resources/mapping/precedence/build.properties b/tycho-pomless/src/test/resources/mapping/precedence/build.properties
deleted file mode 100644
index e69de29..0000000
--- a/tycho-pomless/src/test/resources/mapping/precedence/build.properties
+++ /dev/null
diff --git a/tycho-pomless/src/test/resources/mapping/simple/META-INF/MANIFEST.MF b/tycho-pomless/src/test/resources/mapping/simple/META-INF/MANIFEST.MF
new file mode 100644
index 0000000..4bdf6c2
--- /dev/null
+++ b/tycho-pomless/src/test/resources/mapping/simple/META-INF/MANIFEST.MF
@@ -0,0 +1,6 @@
+Manifest-Version: 1.0
+Bundle-ManifestVersion: 2
+Missing-Bundle-SymbolicName: pomless.bundle;singleton:=true
+Bundle-Version: 0.1.0.qualifier
+Bundle-SymbolicName: simple
+
diff --git a/tycho-pomless/src/test/resources/mapping/simple/build.properties b/tycho-pomless/src/test/resources/mapping/simple/build.properties
deleted file mode 100644
index e69de29..0000000
--- a/tycho-pomless/src/test/resources/mapping/simple/build.properties
+++ /dev/null
diff --git a/tycho-pomless/src/test/resources/modelreader/updatesites/pom.xml b/tycho-pomless/src/test/resources/modelreader/updatesites/pom.xml
index f221da0..3154e65 100644
--- a/tycho-pomless/src/test/resources/modelreader/updatesites/pom.xml
+++ b/tycho-pomless/src/test/resources/modelreader/updatesites/pom.xml
@@ -4,7 +4,7 @@
<modelVersion>4.0.0</modelVersion>
<groupId>testParent.groupId</groupId>
- <artifactId>updatesites-testparent</artifactId>
+ <artifactId>testparent</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>pom</packaging>

Back to the top