/**
* Copyright (c) 2010, 2013 Darmstadt University of Technology.
* 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:
* Olav Lenz - initial API and implementation
*/
package org.eclipse.recommenders.coordinates.osgi;
import static com.google.common.base.Optional.*;
import static org.eclipse.recommenders.coordinates.DependencyType.*;
import static org.hamcrest.CoreMatchers.*;
import static org.junit.Assert.assertThat;
import static org.mockito.Mockito.*;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.Collection;
import java.util.LinkedList;
import java.util.jar.Attributes;
import java.util.jar.JarFile;
import java.util.jar.Manifest;
import org.eclipse.recommenders.coordinates.DependencyInfo;
import org.eclipse.recommenders.coordinates.IProjectCoordinateAdvisor;
import org.eclipse.recommenders.coordinates.ProjectCoordinate;
import org.eclipse.recommenders.utils.Nullable;
import org.eclipse.recommenders.utils.Zips.IFileToJarFileConverter;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.TemporaryFolder;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
import org.junit.runners.Parameterized.Parameters;
import com.google.common.base.Optional;
import com.google.common.collect.Lists;
@RunWith(Parameterized.class)
public class OsgiManifestAdvisorTest {
@Rule
public final TemporaryFolder folder = new TemporaryFolder();
private final String bundleSymbolicName;
private final String bundleVersion;
private final Optional<ProjectCoordinate> expectedCoordinate;
public OsgiManifestAdvisorTest(String description, String bundleSymbolicName, String bundleVersion,
@Nullable ProjectCoordinate expectedCoordinate) {
this.bundleSymbolicName = bundleSymbolicName;
this.bundleVersion = bundleVersion;
this.expectedCoordinate = Optional.fromNullable(expectedCoordinate);
}
@Parameters(name = "{index}: {0} ({1};bundle-version=\"{2}\")")
public static Collection<Object[]> scenarios() {
LinkedList<Object[]> scenarios = Lists.newLinkedList();
scenarios.add(scenario("One-part Bundle-SymbolicName becomes groupId", "example", "1.0.0",
new ProjectCoordinate("example", "example", "1.0.0")));
scenarios.add(scenario("Two-part Bundle-SymbolicName becomes groupId", "org.example", "1.0.0",
new ProjectCoordinate("org.example", "org.example", "1.0.0")));
scenarios.add(scenario("Three-part Bundle-SymbolicName becomes groupId", "org.example.project", "1.0.0",
new ProjectCoordinate("org.example.project", "org.example.project", "1.0.0")));
scenarios.add(scenario("The groupId is limited to first part of unknown top-level domain", "javax.beans",
"1.0.0", new ProjectCoordinate("javax", "javax.beans", "1.0.0")));
scenarios.add(scenario("The groupId is limited to first three parts of Bundle-SymbolicName",
"org.example.project.test", "1.0.0", new ProjectCoordinate("org.example.project",
"org.example.project.test", "1.0.0")));
scenarios.add(scenario("Qualifier of Bundle-Version is stripped", "org.example.project", "1.0.0.qualifier",
new ProjectCoordinate("org.example.project", "org.example.project", "1.0.0")));
scenarios.add(scenario("Expanded qualifier of Bundle-Version is stripped", "org.example.project",
"1.0.0.v20140814-1000", new ProjectCoordinate("org.example.project", "org.example.project", "1.0.0")));
scenarios.add(scenario("Directories of Bundle-SymbolicName are stripped", "org.example.project;singleton=true",
"1.0.0", new ProjectCoordinate("org.example.project", "org.example.project", "1.0.0")));
scenarios.add(scenario("Invalid Bundle-Version", "org.example.project", "1.0-Beta", null));
// See https://bugs.eclipse.org/bugs/show_bug.cgi?id=441751
scenarios
.add(scenario("Invalid domain name in Bundle-SymbolicName", "org.example.project._test", "1.0.0", null));
return scenarios;
}
private static Object[] scenario(String description, String bundleSymbolicName, String bundleVersion,
ProjectCoordinate expectedCoordinate) {
return new Object[] { description, bundleSymbolicName, bundleVersion, expectedCoordinate };
}
@Test
public void testManifestInJarDependency() throws Exception {
File jarFile = folder.newFile("dependency.jar");
DependencyInfo info = new DependencyInfo(jarFile, JAR);
IFileToJarFileConverter fileToJarFileConverter = createFileToJarFileConverter(bundleSymbolicName, bundleVersion);
IProjectCoordinateAdvisor sut = new OsgiManifestAdvisor(fileToJarFileConverter);
Optional<ProjectCoordinate> suggestion = sut.suggest(info);
assertThat(suggestion, is(equalTo(expectedCoordinate)));
}
@Test
public void testManifestInProjectDependency() throws Exception {
File projectDirectory = createProjectWithManifestFile("TestProject", bundleSymbolicName, bundleVersion);
DependencyInfo info = new DependencyInfo(projectDirectory, PROJECT);
IProjectCoordinateAdvisor sut = new OsgiManifestAdvisor();
Optional<ProjectCoordinate> suggestion = sut.suggest(info);
assertThat(suggestion, is(equalTo(expectedCoordinate)));
}
private IFileToJarFileConverter createFileToJarFileConverter(String bundleName, String bundleVersion) {
final Manifest manifest = createManifest(bundleName, bundleVersion);
IFileToJarFileConverter fileToJarFileConverter = new IFileToJarFileConverter() {
@Override
public Optional<JarFile> createJarFile(File file) {
JarFile jarFileMock = mock(JarFile.class);
try {
when(jarFileMock.getManifest()).thenReturn(manifest);
} catch (IOException e) {
return absent();
}
return of(jarFileMock);
}
};
return fileToJarFileConverter;
}
private File createProjectWithManifestFile(String projectName, String bundleSymbolicName, String bundleVersion)
throws IOException {
File projectFolder = folder.newFolder(projectName);
File metaInfFolder = folder.newFolder(projectName, "META-INF");
File manifestFile = new File(metaInfFolder, "MANIFEST.MF");
manifestFile.createNewFile();
Manifest manifest = createManifest(bundleSymbolicName, bundleVersion);
FileOutputStream fileOutputStream = new FileOutputStream(manifestFile);
manifest.write(fileOutputStream);
fileOutputStream.close();
return projectFolder;
}
private Manifest createManifest(String bundleName, String bundleVersion) {
final Manifest manifest = new Manifest();
manifest.getMainAttributes().putValue(OsgiManifestAdvisor.BUNDLE_NAME.toString(), bundleName);
manifest.getMainAttributes().putValue(OsgiManifestAdvisor.BUNDLE_VERSION.toString(), bundleVersion);
manifest.getMainAttributes().putValue(Attributes.Name.MANIFEST_VERSION.toString(), "1.0");
return manifest;
}
}