summaryrefslogtreecommitdiffstatsabout
diff options
context:
space:
mode:
authorRoland Grunberg2012-05-22 09:57:01 (EDT)
committer Jan Sievers2012-05-22 10:25:18 (EDT)
commitf290bd4e4ed15a23d231a04a402faf94b99d3213 (patch)
treefbf86730006f09427b4ebe3d9d9513ebd595f76a
parent01f8c83e62b9e9cca6c3562f347507685dcb07b4 (diff)
downloadorg.eclipse.tycho-f290bd4e4ed15a23d231a04a402faf94b99d3213.zip
org.eclipse.tycho-f290bd4e4ed15a23d231a04a402faf94b99d3213.tar.gz
org.eclipse.tycho-f290bd4e4ed15a23d231a04a402faf94b99d3213.tar.bz2
375160 Add name and vendor attributes to source bundle manifestrefs/changes/75/5775/5
When a source bundle is generated, the bundle's name and vendor attributes should be passed from the original bundle. Bundle-Name and Bundle-Vendor values of the original bundle are i18n-resolved and resolved values (with " Source" appended for Bundle-Name) are used to generate OSGI-INF/l10n/bundle-src.properties for the source bundle. To allow overriding generation, if OSGI-INF/l10n/bundle-src.properties is included in src.includes, this file will not be generated. Default value for Bundle-Name (if missing) is Bundle-SymbolicName. Default value for Bundle-Vendor (if missing) is "unknown". Warnings are logged in both cases. Change-Id: I7982d0578ca9d5ebe61bea6adcd78d35683e0d6f
-rw-r--r--tycho-its/projects/TYCHO192sourceBundles/helloworld/META-INF/MANIFEST.MF2
-rw-r--r--tycho-its/projects/TYCHO192sourceBundles/helloworld/plugin.properties2
-rw-r--r--tycho-its/src/test/java/org/eclipse/tycho/test/TYCHO192sourceBundles/Tycho192SourceBundleTest.java18
-rw-r--r--tycho-source-plugin/src/main/java/org/eclipse/tycho/source/OsgiSourceMojo.java140
4 files changed, 146 insertions, 16 deletions
diff --git a/tycho-its/projects/TYCHO192sourceBundles/helloworld/META-INF/MANIFEST.MF b/tycho-its/projects/TYCHO192sourceBundles/helloworld/META-INF/MANIFEST.MF
index d9ed350..ab8feb1 100644
--- a/tycho-its/projects/TYCHO192sourceBundles/helloworld/META-INF/MANIFEST.MF
+++ b/tycho-its/projects/TYCHO192sourceBundles/helloworld/META-INF/MANIFEST.MF
@@ -2,3 +2,5 @@ Manifest-Version: 1.0
Bundle-ManifestVersion: 2
Bundle-SymbolicName: helloworld
Bundle-Version: 0.1.0.qualifier
+Bundle-Name: %pluginName
+Bundle-Vendor: %pluginVendor \ No newline at end of file
diff --git a/tycho-its/projects/TYCHO192sourceBundles/helloworld/plugin.properties b/tycho-its/projects/TYCHO192sourceBundles/helloworld/plugin.properties
new file mode 100644
index 0000000..c68d29f
--- /dev/null
+++ b/tycho-its/projects/TYCHO192sourceBundles/helloworld/plugin.properties
@@ -0,0 +1,2 @@
+pluginName=Hello Plugin
+pluginVendor=Hello Vendor \ No newline at end of file
diff --git a/tycho-its/src/test/java/org/eclipse/tycho/test/TYCHO192sourceBundles/Tycho192SourceBundleTest.java b/tycho-its/src/test/java/org/eclipse/tycho/test/TYCHO192sourceBundles/Tycho192SourceBundleTest.java
index 580f776..bf7b0ca 100644
--- a/tycho-its/src/test/java/org/eclipse/tycho/test/TYCHO192sourceBundles/Tycho192SourceBundleTest.java
+++ b/tycho-its/src/test/java/org/eclipse/tycho/test/TYCHO192sourceBundles/Tycho192SourceBundleTest.java
@@ -17,7 +17,11 @@ import static org.junit.Assert.assertTrue;
import java.io.File;
import java.io.FileFilter;
import java.io.IOException;
+import java.io.InputStream;
+import java.util.Properties;
+import java.util.jar.Attributes;
import java.util.jar.JarFile;
+import java.util.zip.ZipEntry;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
@@ -32,6 +36,7 @@ import org.apache.maven.it.Verifier;
import org.eclipse.tycho.p2.repository.RepositoryLayoutHelper;
import org.eclipse.tycho.test.AbstractTychoIntegrationTest;
import org.junit.Test;
+import org.osgi.framework.Constants;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.xml.sax.SAXException;
@@ -100,9 +105,20 @@ public class Tycho192SourceBundleTest extends AbstractTychoIntegrationTest {
JarFile sourceJar = new JarFile(sourceJars[0]);
try {
assertNotNull(sourceJar.getEntry("helloworld/MessageProvider.java"));
+ Attributes sourceBundleHeaders = sourceJar.getManifest().getMainAttributes();
+ assertEquals("%bundleName", sourceBundleHeaders.getValue(Constants.BUNDLE_NAME));
+ assertEquals("%bundleVendor", sourceBundleHeaders.getValue(Constants.BUNDLE_VENDOR));
+ assertEquals("OSGI-INF/l10n/bundle-src", sourceBundleHeaders.getValue(Constants.BUNDLE_LOCALIZATION));
+ ZipEntry l10nPropsEntry = sourceJar.getEntry("OSGI-INF/l10n/bundle-src.properties");
+ assertNotNull(l10nPropsEntry);
+ Properties l10nProps = new Properties();
+ InputStream propsStream = sourceJar.getInputStream(l10nPropsEntry);
+ l10nProps.load(propsStream);
+ assertEquals(2, l10nProps.size());
+ assertEquals("Hello Plugin Source", l10nProps.getProperty("bundleName"));
+ assertEquals("Hello Vendor", l10nProps.getProperty("bundleVendor"));
} finally {
sourceJar.close();
}
}
-
}
diff --git a/tycho-source-plugin/src/main/java/org/eclipse/tycho/source/OsgiSourceMojo.java b/tycho-source-plugin/src/main/java/org/eclipse/tycho/source/OsgiSourceMojo.java
index 0c1cbd0..43d5eb5 100644
--- a/tycho-source-plugin/src/main/java/org/eclipse/tycho/source/OsgiSourceMojo.java
+++ b/tycho-source-plugin/src/main/java/org/eclipse/tycho/source/OsgiSourceMojo.java
@@ -10,11 +10,26 @@
*******************************************************************************/
package org.eclipse.tycho.source;
+import static java.util.Collections.singletonList;
+import static org.osgi.framework.Constants.BUNDLE_LOCALIZATION;
+import static org.osgi.framework.Constants.BUNDLE_LOCALIZATION_DEFAULT_BASENAME;
+import static org.osgi.framework.Constants.BUNDLE_MANIFESTVERSION;
+import static org.osgi.framework.Constants.BUNDLE_NAME;
+import static org.osgi.framework.Constants.BUNDLE_SYMBOLICNAME;
+import static org.osgi.framework.Constants.BUNDLE_VENDOR;
+import static org.osgi.framework.Constants.BUNDLE_VERSION;
+
import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.OutputStream;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Map;
+import java.util.Properties;
+import java.util.jar.JarFile;
import org.apache.maven.archiver.MavenArchiveConfiguration;
import org.apache.maven.model.Plugin;
@@ -22,13 +37,16 @@ import org.apache.maven.model.PluginExecution;
import org.apache.maven.model.Resource;
import org.apache.maven.plugin.MojoExecutionException;
import org.apache.maven.project.MavenProject;
+import org.codehaus.plexus.util.IOUtil;
import org.codehaus.plexus.util.xml.Xpp3Dom;
import org.eclipse.tycho.ArtifactKey;
import org.eclipse.tycho.ReactorProject;
import org.eclipse.tycho.core.TychoProject;
import org.eclipse.tycho.core.facade.BuildProperties;
import org.eclipse.tycho.core.facade.BuildPropertiesParser;
+import org.eclipse.tycho.core.osgitools.BundleReader;
import org.eclipse.tycho.core.osgitools.DefaultReactorProject;
+import org.eclipse.tycho.core.osgitools.OsgiManifest;
import org.eclipse.tycho.packaging.IncludeValidationHelper;
import org.osgi.framework.Version;
@@ -44,10 +62,14 @@ public class OsgiSourceMojo extends AbstractSourceJarMojo {
private static final String GOAL = "plugin-source";
- private static final String MANIFEST_HEADER_BUNDLE_MANIFEST_VERSION = "Bundle-ManifestVersion";
- private static final String MANIFEST_HEADER_BUNDLE_SYMBOLIC_NAME = "Bundle-SymbolicName";
- private static final String MANIFEST_HEADER_BUNDLE_VERSION = "Bundle-Version";
private static final String MANIFEST_HEADER_ECLIPSE_SOURCE_BUNDLE = "Eclipse-SourceBundle";
+ private static final String MANIFEST_BUNDLE_LOCALIZATION_BASENAME = BUNDLE_LOCALIZATION_DEFAULT_BASENAME + "-src";
+ private static final String MANIFEST_BUNDLE_LOCALIZATION_FILENAME = MANIFEST_BUNDLE_LOCALIZATION_BASENAME
+ + ".properties";
+ private static final String I18N_KEY_PREFIX = "%";
+ private static final String I18N_KEY_BUNDLE_VENDOR = "bundleVendor";
+ private static final String I18N_KEY_BUNDLE_NAME = "bundleName";
+
private static final String VERSION_QUALIFIER = "qualifier";
/**
@@ -114,6 +136,11 @@ public class OsgiSourceMojo extends AbstractSourceJarMojo {
*/
private IncludeValidationHelper includeValidationHelper;
+ /**
+ * @component
+ */
+ private BundleReader bundleReader;
+
/** {@inheritDoc} */
protected List<String> getSources(MavenProject p) throws MojoExecutionException {
return getSources(project, requireSourceRoots, buildPropertiesParser);
@@ -128,6 +155,7 @@ public class OsgiSourceMojo extends AbstractSourceJarMojo {
sources.add(new File(p.getBasedir(), sourceFolder).getAbsolutePath());
}
}
+
if (requireSourceRoots && sources.isEmpty()) {
throw new MojoExecutionException("no source folders found in build.properties");
}
@@ -141,15 +169,94 @@ public class OsgiSourceMojo extends AbstractSourceJarMojo {
}
BuildProperties buildProperties = buildPropertiesParser.parse(p.getBasedir());
List<String> srcIncludesList = buildProperties.getSourceIncludes();
- if (srcIncludesList.isEmpty()) {
- return Collections.emptyList();
+ List<Resource> resources = new ArrayList<Resource>();
+ if (!srcIncludesList.isEmpty()) {
+ includeValidationHelper.checkSourceIncludesExist(p, buildProperties, strictSrcIncludes);
+ Resource resource = new Resource();
+ resource.setDirectory(project.getBasedir().getAbsolutePath());
+ resource.setExcludes(buildProperties.getSourceExcludes());
+ resource.setIncludes(srcIncludesList);
+ resources.add(resource);
+ }
+ if (!srcIncludesList.contains(MANIFEST_BUNDLE_LOCALIZATION_FILENAME)) {
+ resources.add(generateL10nFile());
+ }
+ return resources;
+ }
+
+ private Resource generateL10nFile() throws MojoExecutionException {
+ OsgiManifest origManifest = bundleReader.loadManifest(project.getBasedir());
+ Properties l10nProps = readL10nProps(origManifest);
+ String bundleName = getL10nResolvedValue(origManifest, BUNDLE_NAME, l10nProps);
+ if (bundleName == null) {
+ getLog().warn(
+ "Bundle-Name header not found in " + new File(project.getBasedir(), JarFile.MANIFEST_NAME)
+ + ", fallback to Bundle-SymbolicName for source bundle");
+ bundleName = origManifest.getBundleSymbolicName();
+ }
+ String sourceBundleName = bundleName + " Source";
+ String bundleVendor = getL10nResolvedValue(origManifest, BUNDLE_VENDOR, l10nProps);
+ if (bundleVendor == null) {
+ getLog().warn(
+ "Bundle-Vendor header not found in " + new File(project.getBasedir(), JarFile.MANIFEST_NAME)
+ + ", fallback to 'unknown' for source bundle");
+ bundleVendor = "unknown";
}
- includeValidationHelper.checkSourceIncludesExist(p, buildProperties, strictSrcIncludes);
- Resource resource = new Resource();
- resource.setDirectory(project.getBasedir().getAbsolutePath());
- resource.setExcludes(buildProperties.getSourceExcludes());
- resource.setIncludes(srcIncludesList);
- return Collections.singletonList(resource);
+ File l10nOutputDir = new File(project.getBuild().getDirectory(), "sourcebundle-l10n-gen");
+ Properties sourceL10nProps = new Properties();
+ sourceL10nProps.setProperty(I18N_KEY_BUNDLE_NAME, sourceBundleName);
+ sourceL10nProps.setProperty(I18N_KEY_BUNDLE_VENDOR, bundleVendor);
+ File l10nPropsFile = new File(l10nOutputDir, MANIFEST_BUNDLE_LOCALIZATION_FILENAME);
+ l10nPropsFile.getParentFile().mkdirs();
+ OutputStream out = null;
+ try {
+ out = new FileOutputStream(l10nPropsFile);
+ sourceL10nProps.store(out, "Source Bundle Localization");
+ } catch (IOException e) {
+ throw new MojoExecutionException("error while generating source bundle localization file", e);
+ } finally {
+ IOUtil.close(out);
+ }
+ Resource l10nResource = new Resource();
+ l10nResource.setDirectory(l10nOutputDir.getAbsolutePath());
+ l10nResource.setIncludes(singletonList(MANIFEST_BUNDLE_LOCALIZATION_FILENAME));
+ return l10nResource;
+ }
+
+ private Properties readL10nProps(OsgiManifest manifest) throws MojoExecutionException {
+ String bundleL10nBase = manifest.getValue(BUNDLE_LOCALIZATION);
+ if (bundleL10nBase == null) {
+ bundleL10nBase = "plugin";
+ }
+ File l10nPropsFile = new File(project.getBasedir(), bundleL10nBase + ".properties");
+ if (!l10nPropsFile.isFile()) {
+ getLog().warn("bundle localization file " + l10nPropsFile + " not found");
+ return null;
+ }
+ Properties l10nProps = new Properties();
+ FileInputStream in = null;
+ try {
+ in = new FileInputStream(l10nPropsFile);
+ l10nProps.load(in);
+ } catch (IOException e) {
+ throw new MojoExecutionException("error loading " + l10nPropsFile, e);
+ } finally {
+ IOUtil.close(in);
+ }
+ return l10nProps;
+ }
+
+ private String getL10nResolvedValue(OsgiManifest manifest, String manifestHeaderKey, Properties l10nProps)
+ throws MojoExecutionException {
+ String value = manifest.getValue(manifestHeaderKey);
+ if (value == null || !value.startsWith("%")) {
+ return value;
+ }
+ if (l10nProps == null) {
+ return null;
+ }
+ String key = value.substring(1).trim();
+ return l10nProps.getProperty(key);
}
/** {@inheritDoc} */
@@ -173,17 +280,20 @@ public class OsgiSourceMojo extends AbstractSourceJarMojo {
String version = artifactKey.getVersion();
if (symbolicName != null && version != null) {
- mavenArchiveConfiguration.addManifestEntry(MANIFEST_HEADER_BUNDLE_MANIFEST_VERSION, "2");
+ mavenArchiveConfiguration.addManifestEntry(BUNDLE_MANIFESTVERSION, "2");
- mavenArchiveConfiguration.addManifestEntry(MANIFEST_HEADER_BUNDLE_SYMBOLIC_NAME, symbolicName
- + sourceBundleSuffix);
+ mavenArchiveConfiguration.addManifestEntry(BUNDLE_SYMBOLICNAME, symbolicName + sourceBundleSuffix);
Version expandedVersion = getExpandedVersion(version);
- mavenArchiveConfiguration.addManifestEntry(MANIFEST_HEADER_BUNDLE_VERSION, expandedVersion.toString());
+ mavenArchiveConfiguration.addManifestEntry(BUNDLE_VERSION, expandedVersion.toString());
mavenArchiveConfiguration.addManifestEntry(MANIFEST_HEADER_ECLIPSE_SOURCE_BUNDLE, symbolicName
+ ";version=\"" + expandedVersion + "\";roots:=\".\"");
+
+ mavenArchiveConfiguration.addManifestEntry(BUNDLE_NAME, I18N_KEY_PREFIX + I18N_KEY_BUNDLE_NAME);
+ mavenArchiveConfiguration.addManifestEntry(BUNDLE_VENDOR, I18N_KEY_PREFIX + I18N_KEY_BUNDLE_VENDOR);
+ mavenArchiveConfiguration.addManifestEntry(BUNDLE_LOCALIZATION, MANIFEST_BUNDLE_LOCALIZATION_BASENAME);
} else {
getLog().info("NOT adding source bundle manifest entries. Incomplete or no bundle information available.");
}