Skip to content

Commit

Permalink
Fix #2337
Browse files Browse the repository at this point in the history
  • Loading branch information
davidfestal committed Oct 7, 2015
1 parent d85504a commit 2d63a10
Show file tree
Hide file tree
Showing 8 changed files with 128 additions and 7 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@ public enum OptionName {
CEYLONUSER("-user"),
CEYLONPASS("-pass"),
CEYLONNOOSGI("-noosgi"),
CEYLONOSGIPROVIDEDBUNDLES("-osgi-provided-bundles"),
CEYLONNOPOM("-nopom"),
CEYLONPACK200("-pack200"),
SOURCEPATH("-sourcepath"),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -147,6 +147,7 @@ public void addClassName(String s) {
CEYLONUSER,
CEYLONPASS,
CEYLONNOOSGI,
CEYLONOSGIPROVIDEDBUNDLES,
CEYLONNOPOM,
CEYLONPACK200,
SOURCEPATH,
Expand Down Expand Up @@ -223,6 +224,7 @@ public void addClassName(String s) {
CEYLONUSER,
CEYLONPASS,
CEYLONNOOSGI,
CEYLONOSGIPROVIDEDBUNDLES,
CEYLONNOPOM,
CEYLONPACK200,
SOURCEPATH,
Expand Down Expand Up @@ -401,6 +403,7 @@ public boolean process(Options options, String option, String arg) {
new COption(CEYLONUSER, "opt.arg.value", "opt.ceylonuser"),
new COption(CEYLONPASS, "opt.arg.value", "opt.ceylonpass"),
new COption(CEYLONNOOSGI, "opt.ceylonnoosgi"),
new COption(CEYLONOSGIPROVIDEDBUNDLES,"opt.arg.value", "opt.ceylonosgiprovidedbundles"),
new COption(CEYLONNOPOM, "opt.ceylonnopom"),
new COption(CEYLONPACK200, "opt.ceylonpack200"),
new COption(CEYLONRESOURCEROOT, "opt.arg.path", "opt.ceylonresourceroot"),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,8 @@ javac.opt.ceylonpass=\
Password for output repository (HTTP only)
javac.opt.ceylonnoosgi=\
Do not generate OSGi module information in META-INF/MANIFEST.MF in the generated car file
javac.opt.ceylonosgiprovidedbundles=\
Comma-separated list of module names. The listed modules are expected to be OSGI bundles provided by the framework, and will be omitted from the 'Required-Bundle' OSGI header in the manifest of the generated car file.
javac.opt.ceylonnopom=\
Do not generate Maven module information in META-INF/maven in the generated car file
javac.opt.pack200=\
Expand Down
18 changes: 18 additions & 0 deletions src/com/redhat/ceylon/ant/CeylonCompileAntTask.java
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,7 @@ public boolean accept(File pathname) {
private FileSet files;
private List<JavacOption> javacOptions = new ArrayList<JavacOption>(0);
private Boolean noOsgi;
private String osgiProvidedBundles;
private Boolean noPom;
private Boolean pack200;
private List<SuppressWarning> suppressWarnings = new ArrayList<SuppressWarning>(0);
Expand All @@ -122,6 +123,20 @@ public boolean getNoOsgi() {
return noOsgi;
}

/**
* Comma-separated list of module names.
* The listed modules are expected to be OSGI bundles provided by the framework,
* and will be omitted from the 'Required-Bundle' OSGI header in the
* manifest of the generated car file.
*/
public void setOsgiProvidedBundles(String osgiProvidedBundles) {
this.osgiProvidedBundles = osgiProvidedBundles;
}

public String getOsgiProvidedBundles() {
return osgiProvidedBundles;
}

/**
* Set to true to disable Maven POM module declaration in the META-INF/maven/ car folder.
*/
Expand Down Expand Up @@ -465,6 +480,9 @@ protected void completeCommandline(Commandline cmd) {
if (noOsgi != null && noOsgi.booleanValue())
appendOption(cmd, "--no-osgi");

if (osgiProvidedBundles != null && !osgiProvidedBundles.isEmpty())
appendOptionArgument(cmd, "--osgi-provided-bundles", osgiProvidedBundles);

if (noPom != null && noPom.booleanValue())
appendOption(cmd, "--no-pom");

Expand Down
15 changes: 15 additions & 0 deletions src/com/redhat/ceylon/compiler/CeylonCompileTool.java
Original file line number Diff line number Diff line change
Expand Up @@ -171,6 +171,7 @@ public void addClassName(String s) {
private String encoding;
private String resourceRoot = DefaultToolOptions.getCompilerResourceRootName();
private boolean noOsgi = DefaultToolOptions.getCompilerNoOsgi();
private String osgiProvidedBundles = DefaultToolOptions.getCompilerOsgiProvidedBundles();
private boolean noPom = DefaultToolOptions.getCompilerNoPom();
private boolean pack200 = DefaultToolOptions.getCompilerPack200();
private EnumSet<Warning> suppressWarnings = EnumUtil.enumsFromStrings(Warning.class, DefaultToolOptions.getCompilerSuppressWarnings());
Expand Down Expand Up @@ -200,6 +201,14 @@ public void setNoOsgi(boolean noOsgi) {
this.noOsgi = noOsgi;
}

@OptionArgument(longName="osgi-provided-bundles", argumentName="modules")
@Description("Comma-separated list of module names. "
+ "The listed modules are expected to be OSGI bundles provided by the framework, "
+ "and will be omitted from the generated MANIFEST 'Required-Bundle' OSGI header.")
public void setOsgiProvidedBundles(String osgiProvidedBundles) {
this.osgiProvidedBundles = osgiProvidedBundles;
}

@Option(longName="no-pom")
@Description("Indicates that the generated car file should not contain Maven POM module declarations.")
public void setNoPom(boolean noPom) {
Expand Down Expand Up @@ -405,6 +414,12 @@ public void initialize(CeylonTool mainTool) throws IOException {
arguments.add("-noosgi");
}

if (osgiProvidedBundles != null
&& ! osgiProvidedBundles.isEmpty()) {
arguments.add("-osgi-provided-bundles");
arguments.add(osgiProvidedBundles);
}

if (noPom) {
arguments.add("-nopom");
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,11 @@
import java.io.Writer;
import java.net.URI;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.List;
import java.util.StringTokenizer;
import java.util.TimeZone;
import java.util.jar.Attributes;
import java.util.jar.JarOutputStream;
Expand All @@ -55,13 +59,15 @@ public class JarEntryManifestFileObject implements JavaFileObject {
private String fileName;
private String jarFileName;
private Module module;
private String osgiProvidedBundles;

public JarEntryManifestFileObject(String jarFileName, JarOutputStream jarFile, String fileName, Module module) {
public JarEntryManifestFileObject(String jarFileName, JarOutputStream jarFile, String fileName, Module module, String osgiProvidedBundles) {
super();
this.jarFileName = jarFileName;
this.jarFile = jarFile;
this.fileName = fileName;
this.module = module;
this.osgiProvidedBundles = osgiProvidedBundles;
}

/*
Expand All @@ -80,7 +86,7 @@ public void close() throws IOException {
}

private void writeManifestJarEntry(Manifest originalManifest) throws IOException {
Manifest manifest = new OsgiManifest(module, originalManifest).build();
Manifest manifest = new OsgiManifest(module, originalManifest, osgiProvidedBundles).build();
jarFile.putNextEntry(new ZipEntry(fileName));
manifest.write(jarFile);
}
Expand Down Expand Up @@ -190,6 +196,8 @@ public static class OsgiManifest {
static {
formatter.setTimeZone(TimeZone.getTimeZone("GMT"));
}

private String osgiProvidedBundles;

public static boolean isManifestFileName(String fileName) {
return MANIFEST_FILE_NAME.equalsIgnoreCase(fileName);
Expand All @@ -198,13 +206,14 @@ public static boolean isManifestFileName(String fileName) {
private final Manifest originalManifest;
private final Module module;

public OsgiManifest(Module module) {
this(module, null);
public OsgiManifest(Module module, String osgiProvidedBundles) {
this(module, null, osgiProvidedBundles);
}

public OsgiManifest(Module module, Manifest originalManifest) {
public OsgiManifest(Module module, Manifest originalManifest, String osgiProvidedBundles) {
this.module = module;
this.originalManifest = originalManifest;
this.osgiProvidedBundles = osgiProvidedBundles;
}

private String toOSGIBundleVersion(String ceylonVersion) {
Expand Down Expand Up @@ -336,6 +345,11 @@ private String getJavaVersion(String jvmVersion) {
* Composes OSGi Require-Bundle header content.
*/
private String getRequireBundle() {
List<String> providedBundles = null;
if (osgiProvidedBundles != null && !osgiProvidedBundles.isEmpty()) {
providedBundles = Arrays.asList(osgiProvidedBundles.split("(,| )+"));
}

StringBuilder requires = new StringBuilder();
boolean distImportAlreadyFound = false;
for (ModuleImport anImport : module.getImports()) {
Expand All @@ -344,6 +358,11 @@ private String getRequireBundle() {
}
Module m = anImport.getModule();
String moduleName = m.getNameAsString();

if (providedBundles != null && providedBundles.contains(moduleName)) {
continue;
}

if ("com.redhat.ceylon.dist".equals(moduleName)) {
distImportAlreadyFound = true;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,7 @@ static class ProgressiveJar {
private Set<String> folders = new HashSet<String>();
private boolean manifestWritten = false;
private boolean writeOsgiManifest;
private String osgiProvidedBundles;
private final String resourceRootPath;
private boolean writeMavenManifest;
private TaskListener taskListener;
Expand All @@ -144,6 +145,7 @@ public ProgressiveJar(RepositoryManager repoManager, Module module, Log log, Opt
options.get(OptionName.VERBOSE) != null, cmrLog);
this.module = module;
this.writeOsgiManifest = !options.isSet(OptionName.CEYLONNOOSGI);
this.osgiProvidedBundles = options.get(OptionName.CEYLONOSGIPROVIDEDBUNDLES);
this.writeMavenManifest = !options.isSet(OptionName.CEYLONNOPOM);

// Determine the special path that signals that the files it contains
Expand Down Expand Up @@ -206,7 +208,7 @@ public void close() throws IOException {
resourceCreator.copy(modifiedResourceFilesFull);

if (writeOsgiManifest && !manifestWritten && !module.isDefault()) {
Manifest manifest = new OsgiManifest(module, getPreviousManifest()).build();
Manifest manifest = new OsgiManifest(module, getPreviousManifest(), osgiProvidedBundles).build();
writeManifestJarEntry(manifest);
}
if (writeMavenManifest) {
Expand Down Expand Up @@ -330,7 +332,7 @@ public JavaFileObject getJavaFileObject(String fileName, File sourceFile) {
modifiedResourceFilesFull.add(FileUtil.applyPath(resourceCreator.getPaths(), fileName).getPath());
if (writeOsgiManifest && OsgiManifest.isManifestFileName(entryName) && !module.isDefault()) {
this.manifestWritten = true;
return new JarEntryManifestFileObject(outputJarFile.getPath(), jarOutputStream, entryName, module);
return new JarEntryManifestFileObject(outputJarFile.getPath(), jarOutputStream, entryName, module, osgiProvidedBundles);
}
}
return new JarEntryFileObject(outputJarFile.getPath(), jarOutputStream, entryName);
Expand Down
61 changes: 61 additions & 0 deletions test/src/com/redhat/ceylon/compiler/java/test/cmr/CMRTests.java
Original file line number Diff line number Diff line change
Expand Up @@ -1316,6 +1316,67 @@ public void testMdlOsgiManifestRequresImportedModules() throws IOException {
"com.redhat.ceylon.dist;bundle-version="+Versions.CEYLON_VERSION_NUMBER+";visibility:=reexport"));
}

@Test
public void testMdlOsgiManifestFiltersProvidedBundles() throws IOException {
compile("modules/osgi/a/module.ceylon",
"modules/osgi/a/package.ceylon",
"modules/osgi/a/A.ceylon");

ArrayList<String> options = new ArrayList<>(defaultOptions);
options.addAll(Arrays.asList(
"-osgi-provided-bundles",
"com.redhat.ceylon.compiler.java.test.cmr.modules.osgi.a , ceylon.language"));

compilesWithoutWarnings(
options,
"modules/osgi/b/module.ceylon",
"modules/osgi/b/package.ceylon",
"modules/osgi/b/B.ceylon");

final String moduleBName = "com.redhat.ceylon.compiler.java.test.cmr.modules.osgi.b";
final String moduleVersion = "1.1.0";

final Manifest manifest = getManifest(moduleBName, moduleVersion);

final String[] requireBundle = ((String) manifest.getMainAttributes()
.get(OsgiManifest.Require_Bundle)).split(",");
assertEquals(1, requireBundle.length);

assertThat(Arrays.asList(requireBundle), CoreMatchers.hasItems(
"com.redhat.ceylon.dist;bundle-version="+Versions.CEYLON_VERSION_NUMBER+";visibility:=reexport"));
}

@Test
public void testMdlOsgiManifestFiltersProvidedBundle() throws IOException {
compile("modules/osgi/a/module.ceylon",
"modules/osgi/a/package.ceylon",
"modules/osgi/a/A.ceylon");

ArrayList<String> options = new ArrayList<>(defaultOptions);
options.addAll(Arrays.asList(
"-osgi-provided-bundles",
"com.redhat.ceylon.compiler.java.test.cmr.modules.osgi.a"));

compilesWithoutWarnings(
options,
"modules/osgi/b/module.ceylon",
"modules/osgi/b/package.ceylon",
"modules/osgi/b/B.ceylon");

final String moduleBName = "com.redhat.ceylon.compiler.java.test.cmr.modules.osgi.b";
final String moduleVersion = "1.1.0";

final Manifest manifest = getManifest(moduleBName, moduleVersion);

final String[] requireBundle = ((String) manifest.getMainAttributes()
.get(OsgiManifest.Require_Bundle)).split(",");
assertEquals(2, requireBundle.length);

assertThat(Arrays.asList(requireBundle), CoreMatchers.hasItems(
"ceylon.language;bundle-version="+Versions.CEYLON_VERSION_NUMBER+";visibility:=reexport",
"com.redhat.ceylon.dist;bundle-version="+Versions.CEYLON_VERSION_NUMBER+";visibility:=reexport"));
}

@Test
public void testMdlOsgiManifestReexportsSharedImportedModules() throws IOException {
compile("modules/osgi/a/module.ceylon",
Expand Down

0 comments on commit 2d63a10

Please sign in to comment.