diff --git a/plugins/maven/lib/plexus-archiver-2.4.4.jar b/plugins/maven/lib/plexus-archiver-2.4.4.jar
new file mode 100644
index 000000000000..1a73adb04868
Binary files /dev/null and b/plugins/maven/lib/plexus-archiver-2.4.4.jar differ
diff --git a/plugins/maven/maven.iml b/plugins/maven/maven.iml
index 9afe51486f6f..231a57e4db15 100644
--- a/plugins/maven/maven.iml
+++ b/plugins/maven/maven.iml
@@ -63,6 +63,15 @@
+
+
+
+
+
+
+
+
+
diff --git a/plugins/maven/src/main/java/org/jetbrains/idea/maven/importing/ManifestImporter.java b/plugins/maven/src/main/java/org/jetbrains/idea/maven/importing/ManifestImporter.java
new file mode 100644
index 000000000000..65fb06cebfce
--- /dev/null
+++ b/plugins/maven/src/main/java/org/jetbrains/idea/maven/importing/ManifestImporter.java
@@ -0,0 +1,85 @@
+/*
+ * Copyright 2000-2014 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.jetbrains.idea.maven.importing;
+
+import com.intellij.openapi.extensions.ExtensionPointName;
+import com.intellij.openapi.roots.DependencyScope;
+import org.jdom.Element;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+import org.jetbrains.idea.maven.model.MavenArtifact;
+import org.jetbrains.idea.maven.project.MavenProject;
+
+import static org.jetbrains.idea.maven.utils.ManifestBuilder.getClasspathPrefix;
+
+/**
+ * @author Vladislav.Soroka
+ * @since 5/26/2014
+ */
+public abstract class ManifestImporter {
+ public static ExtensionPointName EXTENSION_POINT_NAME =
+ ExtensionPointName.create("org.jetbrains.idea.maven.manifestImporter");
+
+ @NotNull
+ public static ManifestImporter getManifestImporter(@NotNull String packaging) {
+ for (ManifestImporter importer : EXTENSION_POINT_NAME.getExtensions()) {
+ if (importer.isApplicable(packaging)) {
+ return importer;
+ }
+ }
+ return new DefaultManifestImporter();
+ }
+
+ @NotNull
+ public String getClasspath(@NotNull MavenProject mavenProject,
+ @Nullable Element manifestConfiguration) {
+ StringBuilder classpath = new StringBuilder();
+ String classpathPrefix = getClasspathPrefix(manifestConfiguration);
+ for (MavenArtifact mavenArtifact : mavenProject.getDependencies()) {
+ final DependencyScope scope = MavenModuleImporter.selectScope(mavenArtifact.getScope());
+ if (scope.isForProductionRuntime()) {
+ if (classpath.length() > 0) {
+ classpath.append(" ");
+ }
+ classpath.append(classpathPrefix);
+ String artifactFileName = mavenArtifact.getArtifactId() + "-" + mavenArtifact.getVersion() + "." + mavenArtifact.getExtension();
+ classpath.append(doGetClasspathItem(mavenProject, mavenArtifact, artifactFileName));
+ }
+ }
+ return classpath.toString();
+ }
+
+ protected abstract boolean isApplicable(String packaging);
+
+ protected abstract String doGetClasspathItem(@NotNull MavenProject mavenProject,
+ @NotNull MavenArtifact mavenArtifact,
+ @NotNull String artifactFileName);
+
+ private static class DefaultManifestImporter extends ManifestImporter {
+
+ @Override
+ protected boolean isApplicable(String packaging) {
+ return true;
+ }
+
+ @Override
+ protected String doGetClasspathItem(@NotNull MavenProject mavenProject,
+ @NotNull MavenArtifact mavenArtifact,
+ @NotNull String artifactFileName) {
+ return artifactFileName;
+ }
+ }
+}
diff --git a/plugins/maven/src/main/java/org/jetbrains/idea/maven/project/MavenResourceCompilerConfigurationGenerator.java b/plugins/maven/src/main/java/org/jetbrains/idea/maven/project/MavenResourceCompilerConfigurationGenerator.java
index 4a8365c3f830..86f73e9721fa 100644
--- a/plugins/maven/src/main/java/org/jetbrains/idea/maven/project/MavenResourceCompilerConfigurationGenerator.java
+++ b/plugins/maven/src/main/java/org/jetbrains/idea/maven/project/MavenResourceCompilerConfigurationGenerator.java
@@ -7,14 +7,17 @@ import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.module.Module;
import com.intellij.openapi.module.ModuleManager;
import com.intellij.openapi.project.Project;
+import com.intellij.openapi.projectRoots.Sdk;
import com.intellij.openapi.roots.*;
import com.intellij.openapi.util.Comparing;
import com.intellij.openapi.util.JDOMUtil;
import com.intellij.openapi.util.io.FileUtil;
+import com.intellij.openapi.util.io.StreamUtil;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.openapi.vfs.LocalFileSystem;
import com.intellij.openapi.vfs.VfsUtil;
import com.intellij.openapi.vfs.VirtualFile;
+import com.intellij.packaging.impl.elements.ManifestFileUtil;
import com.intellij.util.containers.ContainerUtil;
import com.intellij.util.xmlb.XmlSerializer;
import org.jdom.Document;
@@ -23,12 +26,14 @@ import org.jetbrains.annotations.NotNull;
import org.jetbrains.idea.maven.dom.references.MavenFilteredPropertyPsiReferenceProvider;
import org.jetbrains.idea.maven.model.MavenId;
import org.jetbrains.idea.maven.model.MavenResource;
+import org.jetbrains.idea.maven.utils.ManifestBuilder;
import org.jetbrains.idea.maven.utils.MavenJDOMUtil;
import org.jetbrains.idea.maven.utils.MavenUtil;
import org.jetbrains.jps.maven.model.impl.*;
import java.io.*;
import java.util.*;
+import java.util.jar.Manifest;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
@@ -146,6 +151,8 @@ public class MavenResourceCompilerConfigurationGenerator {
}
projectConfig.moduleConfigurations.put(module.getName(), resourceConfig);
+
+ generateManifest(mavenProject, module);
}
addNonMavenResources(projectConfig);
@@ -175,6 +182,35 @@ public class MavenResourceCompilerConfigurationGenerator {
});
}
+ private static void generateManifest(@NotNull MavenProject mavenProject, @NotNull Module module) {
+ try {
+ String jdkVersion = null;
+ Sdk sdk = ModuleRootManager.getInstance(module).getSdk();
+ if (sdk != null && (jdkVersion = sdk.getVersionString()) != null) {
+ final int quoteIndex = jdkVersion.indexOf('"');
+ if (quoteIndex != -1) {
+ jdkVersion = jdkVersion.substring(quoteIndex + 1, jdkVersion.length() - 1);
+ }
+ }
+ Manifest manifest = new ManifestBuilder(mavenProject).withJdkVersion(jdkVersion).build();
+ File manifestFile = new File(mavenProject.getBuildDirectory(), ManifestFileUtil.MANIFEST_FILE_NAME);
+ FileUtil.createIfDoesntExist(manifestFile);
+ OutputStream outputStream = new FileOutputStream(manifestFile);
+ try {
+ manifest.write(outputStream);
+ }
+ finally {
+ StreamUtil.closeStream(outputStream);
+ }
+ }
+ catch (ManifestBuilder.ManifestBuilderException e) {
+ LOG.error("Unable to generate artifact manifest", e);
+ }
+ catch (IOException e) {
+ LOG.error("Unable to save generated artifact manifest", e);
+ }
+ }
+
private Properties getFilteringProperties(MavenProject mavenProject) {
final Properties properties = new Properties();
diff --git a/plugins/maven/src/main/java/org/jetbrains/idea/maven/utils/ManifestBuilder.java b/plugins/maven/src/main/java/org/jetbrains/idea/maven/utils/ManifestBuilder.java
new file mode 100644
index 000000000000..eaeacedf72b0
--- /dev/null
+++ b/plugins/maven/src/main/java/org/jetbrains/idea/maven/utils/ManifestBuilder.java
@@ -0,0 +1,317 @@
+/*
+ * Copyright 2000-2014 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.jetbrains.idea.maven.utils;
+
+import com.intellij.openapi.util.Pair;
+import com.intellij.openapi.util.io.StreamUtil;
+import com.intellij.openapi.util.text.StringUtil;
+import com.intellij.util.containers.ContainerUtil;
+import org.codehaus.plexus.archiver.jar.Manifest;
+import org.codehaus.plexus.archiver.jar.ManifestException;
+import org.jdom.Element;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+import org.jetbrains.idea.maven.importing.ManifestImporter;
+import org.jetbrains.idea.maven.project.MavenProject;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Set;
+import java.util.jar.Attributes;
+
+import static org.codehaus.plexus.archiver.jar.Manifest.Attribute;
+
+/**
+ * @author Vladislav.Soroka
+ * @since 5/22/2014
+ */
+public class ManifestBuilder {
+
+ private static final Map PACKAGING_PLUGINS = ContainerUtil.newHashMap(
+ Pair.create("jar", "maven-jar-plugin"),
+ Pair.create("ejb", "maven-ejb-plugin"),
+ Pair.create("ejb-client", "maven-ejb-plugin"),
+ Pair.create("war", "maven-war-plugin"),
+ Pair.create("ear", "maven-ear-plugin")
+ );
+
+ @NotNull private final MavenProject myMavenProject;
+ @Nullable private String myJdkVersion;
+
+ public ManifestBuilder(@NotNull MavenProject mavenProject) {
+ myMavenProject = mavenProject;
+ }
+
+ public ManifestBuilder withJdkVersion(String jdkVersion) {
+ myJdkVersion = jdkVersion;
+ return this;
+ }
+
+ @NotNull
+ public java.util.jar.Manifest build() throws ManifestBuilderException {
+ try {
+ Element mavenPackagingPluginConfiguration = null;
+ final String packaging = myMavenProject.getPackaging();
+ if (StringUtil.isEmpty(packaging)) {
+ mavenPackagingPluginConfiguration = myMavenProject.getPluginConfiguration("org.apache.maven.plugins", "maven-jar-plugin");
+ }
+ else {
+ final String pluginArtifactId = PACKAGING_PLUGINS.get(StringUtil.toLowerCase(packaging));
+ if (pluginArtifactId != null) {
+ mavenPackagingPluginConfiguration = myMavenProject.getPluginConfiguration("org.apache.maven.plugins", pluginArtifactId);
+ }
+ }
+
+ final Element mavenArchiveConfiguration =
+ mavenPackagingPluginConfiguration != null ? mavenPackagingPluginConfiguration.getChild("archive") : null;
+
+ if (mavenArchiveConfiguration == null) return getDefaultManifest(Collections.emptyMap());
+
+ final Element manifestEntries = mavenArchiveConfiguration.getChild("manifestEntries");
+ Map entries = getManifestEntries(manifestEntries);
+
+ final Element manifestConfiguration = mavenArchiveConfiguration.getChild("manifest");
+ final Manifest configuredManifest = getConfiguredManifest(myMavenProject, manifestConfiguration, entries);
+
+ if (!entries.isEmpty()) {
+ addManifestEntries(configuredManifest, entries);
+ }
+
+ addCustomManifestSections(configuredManifest, mavenArchiveConfiguration);
+
+ Manifest finalManifest = getDefaultManifest(entries);
+ // merge configured manifest
+ merge(finalManifest, configuredManifest);
+
+ // merge user supplied manifest
+ final Manifest userSuppliedManifest = getUserSuppliedManifest(mavenArchiveConfiguration);
+ merge(finalManifest, userSuppliedManifest);
+ return finalManifest;
+ }
+ catch (ManifestException e) {
+ throw new ManifestBuilderException(e);
+ }
+ }
+
+ @NotNull
+ public static String getClasspathPrefix(@Nullable Element manifestConfiguration) {
+ String classpathPrefix = MavenJDOMUtil.findChildValueByPath(manifestConfiguration, "classpathPrefix", "").replaceAll("\\\\", "/");
+ if (classpathPrefix.length() != 0 && !classpathPrefix.endsWith("/")) {
+ classpathPrefix += "/";
+ }
+ return classpathPrefix;
+ }
+
+
+ private static Map getManifestEntries(Element manifestEntries) {
+ boolean hasManifestEntries = manifestEntries != null && manifestEntries.getContentSize() > 0;
+ Map entries = hasManifestEntries ?
+ new HashMap(manifestEntries.getContentSize()) :
+ Collections.emptyMap();
+ if (hasManifestEntries) {
+ for (Element element : manifestEntries.getChildren()) {
+ entries.put(element.getName(), element.getTextTrim());
+ }
+ }
+ return entries;
+ }
+
+ private static void addCustomManifestSections(@NotNull Manifest manifest, @NotNull Element mavenArchiveConfiguration)
+ throws ManifestException {
+
+ for (Element section : MavenJDOMUtil.findChildrenByPath(mavenArchiveConfiguration, "manifestSections", "manifestSection")) {
+ Manifest.Section theSection = new Manifest.Section();
+
+ final String sectionName = MavenJDOMUtil.findChildValueByPath(section, "name");
+ theSection.setName(sectionName);
+
+ final Element manifestEntries = section.getChild("manifestEntries");
+ Map entries = getManifestEntries(manifestEntries);
+
+ if (!entries.isEmpty()) {
+ for (Map.Entry entry : entries.entrySet()) {
+ Attribute attr = new Attribute(entry.getKey(), entry.getValue());
+ theSection.addConfiguredAttribute(attr);
+ }
+ }
+ manifest.addConfiguredSection(theSection);
+ }
+ }
+
+ @NotNull
+ private Manifest getDefaultManifest(@NotNull Map entries) throws ManifestException {
+ Manifest finalManifest = new Manifest();
+ addManifestAttribute(finalManifest, entries, "Created-By", "IntelliJ IDEA");
+ addManifestAttribute(finalManifest, entries, "Built-By", System.getProperty("user.name"));
+ if (!StringUtil.isEmpty(myJdkVersion)) {
+ addManifestAttribute(finalManifest, entries, "Build-Jdk", myJdkVersion);
+ }
+ return finalManifest;
+ }
+
+ private static void addManifestEntries(@NotNull Manifest manifest, @NotNull Map entries)
+ throws ManifestException {
+ if (!entries.isEmpty()) {
+ for (Map.Entry entry : entries.entrySet()) {
+ Attribute attr = manifest.getMainSection().getAttribute(entry.getKey());
+ if ("Class-Path".equals(entry.getKey()) && attr != null) {
+ // Merge the user-supplied Class-Path value with the programmatically
+ // generated Class-Path. Note that the user-supplied value goes first
+ // so that resources there will override any in the standard Class-Path.
+ attr.setValue(entry.getValue() + " " + attr.getValue());
+ }
+ else {
+ addManifestAttribute(manifest, entry.getKey(), entry.getValue());
+ }
+ }
+ }
+
+ Set keys = entries.keySet();
+ for (String key : keys) {
+ String value = entries.get(key);
+ Attribute attr = manifest.getMainSection().getAttribute(key);
+ if (key.equals("Class-Path") && attr != null) {
+ // Merge the user-supplied Class-Path value with the programmatically
+ // generated Class-Path. Note that the user-supplied value goes first
+ // so that resources there will override any in the standard Class-Path.
+ attr.setValue(value + " " + attr.getValue());
+ }
+ else {
+ addManifestAttribute(manifest, key, value);
+ }
+ }
+ }
+
+ @Nullable
+ private Manifest getUserSuppliedManifest(@Nullable Element mavenArchiveConfiguration) {
+ Manifest manifest = null;
+ String manifestPath = MavenJDOMUtil.findChildValueByPath(mavenArchiveConfiguration, "manifestFile");
+ if (manifestPath != null) {
+ File manifestFile = new File(manifestPath);
+ if (!manifestFile.isAbsolute()) {
+ manifestFile = new File(myMavenProject.getDirectory(), manifestPath);
+ }
+ if (manifestFile.isFile()) {
+ FileInputStream fis = null;
+ try {
+ //noinspection IOResourceOpenedButNotSafelyClosed
+ fis = new FileInputStream(manifestFile);
+ manifest = new Manifest(fis);
+ }
+ catch (IOException ignore) {
+ }
+ finally {
+ StreamUtil.closeStream(fis);
+ }
+ }
+ }
+
+ return manifest;
+ }
+
+ @NotNull
+ private static Manifest getConfiguredManifest(@NotNull MavenProject mavenProject,
+ @Nullable Element manifestConfiguration,
+ @NotNull Map entries) throws ManifestException {
+ final Manifest manifest = new Manifest();
+
+ boolean isAddDefaultSpecificationEntries =
+ Boolean.valueOf(MavenJDOMUtil.findChildValueByPath(manifestConfiguration, "addDefaultSpecificationEntries", "false"));
+ if (isAddDefaultSpecificationEntries) {
+ addManifestAttribute(manifest, entries, "Specification-Title", mavenProject.getName());
+ addManifestAttribute(manifest, entries, "Specification-Version", mavenProject.getMavenId().getVersion());
+ }
+
+ boolean isAddDefaultImplementationEntries =
+ Boolean.valueOf(MavenJDOMUtil.findChildValueByPath(manifestConfiguration, "addDefaultImplementationEntries", "false"));
+ if (isAddDefaultImplementationEntries) {
+ addManifestAttribute(manifest, entries, "Implementation-Title", mavenProject.getName());
+ addManifestAttribute(manifest, entries, "Implementation-Version", mavenProject.getMavenId().getVersion());
+ addManifestAttribute(manifest, entries, "Implementation-Vendor-Id", mavenProject.getMavenId().getGroupId());
+ }
+
+ String packageName = MavenJDOMUtil.findChildValueByPath(manifestConfiguration, "packageName");
+ if (packageName != null) {
+ addManifestAttribute(manifest, entries, "Package", packageName);
+ }
+
+ String mainClass = MavenJDOMUtil.findChildValueByPath(manifestConfiguration, "mainClass");
+ if (!StringUtil.isEmpty(mainClass)) {
+ addManifestAttribute(manifest, entries, "Main-Class", mainClass);
+ }
+
+ boolean isAddClasspath = Boolean.valueOf(MavenJDOMUtil.findChildValueByPath(manifestConfiguration, "addClasspath", "false"));
+ if (isAddClasspath) {
+ final ManifestImporter manifestImporter = ManifestImporter.getManifestImporter(mavenProject.getPackaging());
+ String classpath = manifestImporter.getClasspath(mavenProject, manifestConfiguration);
+ if (!classpath.isEmpty()) {
+ addManifestAttribute(manifest, "Class-Path", classpath);
+ }
+ }
+ return manifest;
+ }
+
+ private static void addManifestAttribute(@NotNull Manifest manifest, @NotNull Map map, String key, String value)
+ throws ManifestException {
+ if (map.containsKey(key)) return;
+ addManifestAttribute(manifest, key, value);
+ }
+
+ private static void addManifestAttribute(@NotNull Manifest manifest, String key, String value) throws ManifestException {
+ if (!StringUtil.isEmpty(value)) {
+ Attribute attr = new Attribute(key, value);
+ manifest.addConfiguredAttribute(attr);
+ }
+ }
+
+ private static void merge(@NotNull java.util.jar.Manifest target, @Nullable java.util.jar.Manifest other) {
+ if (other != null) {
+ mergeAttributes(target.getMainAttributes(), other.getMainAttributes());
+
+ for (Map.Entry o : other.getEntries().entrySet()) {
+ Attributes ourSection = target.getAttributes(o.getKey());
+ Attributes otherSection = o.getValue();
+ if (ourSection == null) {
+ if (otherSection != null) {
+ target.getEntries().put(o.getKey(), (Attributes)otherSection.clone());
+ }
+ }
+ else {
+ mergeAttributes(ourSection, otherSection);
+ }
+ }
+ }
+ }
+
+ private static void mergeAttributes(@NotNull Attributes target, @NotNull Attributes section) {
+ for (Object o : section.keySet()) {
+ Attributes.Name key = (Attributes.Name)o;
+ final Object value = section.get(o);
+ target.put(key, value);
+ }
+ }
+
+
+ public static class ManifestBuilderException extends Exception {
+ public ManifestBuilderException(Throwable cause) {
+ super(cause);
+ }
+ }
+}
diff --git a/plugins/maven/src/main/resources/META-INF/plugin.xml b/plugins/maven/src/main/resources/META-INF/plugin.xml
index 303c92f1b56c..9580f83405ed 100644
--- a/plugins/maven/src/main/resources/META-INF/plugin.xml
+++ b/plugins/maven/src/main/resources/META-INF/plugin.xml
@@ -21,6 +21,7 @@
+
diff --git a/plugins/maven/src/test/java/org/jetbrains/idea/maven/compiler/ManifestGenerationTest.java b/plugins/maven/src/test/java/org/jetbrains/idea/maven/compiler/ManifestGenerationTest.java
new file mode 100644
index 000000000000..bdb025bf3edf
--- /dev/null
+++ b/plugins/maven/src/test/java/org/jetbrains/idea/maven/compiler/ManifestGenerationTest.java
@@ -0,0 +1,224 @@
+/*
+ * Copyright 2000-2014 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.jetbrains.idea.maven.compiler;
+
+import com.intellij.openapi.module.Module;
+import com.intellij.openapi.projectRoots.Sdk;
+import com.intellij.openapi.roots.ModuleRootManager;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+/**
+ * @author Vladislav.Soroka
+ * @since 5/23/2014
+ */
+public class ManifestGenerationTest extends MavenCompilingTestCase {
+ @Override
+ protected boolean useJps() {
+ return true;
+ }
+
+ public void testBasic() throws Exception {
+ importProject("test" +
+ "project" +
+ "1");
+
+ compileModules("project");
+
+ assertSameLinesWithFile(getProjectPath() + "/target/MANIFEST.MF",
+ "Manifest-Version: 1.0\n" +
+ "Build-Jdk: " + extractJdkVersion(getModule("project")) + "\n" +
+ "Built-By: " + System.getProperty("user.name") + "\n" +
+ "Created-By: IntelliJ IDEA");
+ }
+
+ public void testClasspathEntry() throws Exception {
+ importProject("test" +
+ "project" +
+ "1" +
+
+ "" +
+ " " +
+ " test" +
+ " other-project" +
+ " 1" +
+ " " +
+ "" +
+
+ "" +
+ " " +
+ " " +
+ " maven-jar-plugin" +
+ " 2.4" +
+ " " +
+ " " +
+ " " +
+ " true" +
+ " lib" +
+ " " +
+ " " +
+ " " +
+ " " +
+ " " +
+ "");
+
+ compileModules("project");
+
+ assertSameLinesWithFile(getProjectPath() + "/target/MANIFEST.MF",
+ "Manifest-Version: 1.0\n" +
+ "Class-Path: lib/other-project-1.jar\n" +
+ "Build-Jdk: " + extractJdkVersion(getModule("project")) + "\n" +
+ "Built-By: " + System.getProperty("user.name") + "\n" +
+ "Created-By: IntelliJ IDEA\n");
+ }
+
+ public void testDefaultEntries() throws Exception {
+ importProject("test" +
+ "project" +
+ "1" +
+
+ "" +
+ " " +
+ " test" +
+ " other-project" +
+ " 1" +
+ " " +
+ "" +
+
+ "" +
+ " " +
+ " " +
+ " maven-jar-plugin" +
+ " 2.4" +
+ " " +
+ " " +
+ " " +
+ " true" +
+ " true" +
+ " " +
+ " " +
+ " " +
+ " " +
+ " " +
+ "");
+
+ compileModules("project");
+
+ assertSameLinesWithFile(getProjectPath() + "/target/MANIFEST.MF",
+ "Manifest-Version: 1.0\n" +
+ "Implementation-Version: 1\n" +
+ "Implementation-Vendor-Id: test\n" +
+ "Build-Jdk: " + extractJdkVersion(getModule("project")) + "\n" +
+ "Built-By: " + System.getProperty("user.name") + "\n" +
+ "Created-By: IntelliJ IDEA\n" +
+ "Specification-Version: 1");
+ }
+
+
+ public void testManifestEntries() throws Exception {
+ importProject("test" +
+ "project" +
+ "1" +
+
+ "" +
+ " " +
+ " " +
+ " maven-jar-plugin" +
+ " 2.4" +
+ " " +
+ " " +
+ " " +
+ " some.package" +
+ " other entry value " +
+ " " +
+ " " +
+ " " +
+ " " +
+ " " +
+ "");
+
+ compileModules("project");
+
+ assertSameLinesWithFile(getProjectPath() + "/target/MANIFEST.MF",
+ "Manifest-Version: 1.0\n" +
+ "otherEntry: other entry value\n" +
+ "Dependencies: some.package\n" +
+ "Build-Jdk: " + extractJdkVersion(getModule("project")) + "\n" +
+ "Built-By: " + System.getProperty("user.name") + "\n" +
+ "Created-By: IntelliJ IDEA");
+ }
+
+ public void testManifestSections() throws Exception {
+ importProject("test" +
+ "project" +
+ "1" +
+
+ "" +
+ " " +
+ " " +
+ " maven-jar-plugin" +
+ " 2.4" +
+ " " +
+ " " +
+ " " +
+ " " +
+ " org/test/Some.class" +
+ " " +
+ " true" +
+ " " +
+ " " +
+ " " +
+ " org/test/SomeOther.class" +
+ " " +
+ " true" +
+ " " +
+ " " +
+ " " +
+ " " +
+ " " +
+ " " +
+ " " +
+ "");
+
+ compileModules("project");
+
+ assertSameLinesWithFile(getProjectPath() + "/target/MANIFEST.MF",
+ "Manifest-Version: 1.0\n" +
+ "Build-Jdk: " + extractJdkVersion(getModule("project")) + "\n" +
+ "Built-By: " + System.getProperty("user.name") + "\n" +
+ "Created-By: IntelliJ IDEA\n" +
+ "\n" +
+ "Name: org/test/SomeOther.class\n" +
+ "Java-Bean: true\n" +
+ "\n" +
+ "Name: org/test/Some.class\n" +
+ "Java-Bean: true");
+ }
+
+ @Nullable
+ public static String extractJdkVersion(@NotNull Module module) {
+ String jdkVersion = null;
+ Sdk sdk = ModuleRootManager.getInstance(module).getSdk();
+ if (sdk != null && (jdkVersion = sdk.getVersionString()) != null) {
+ final int quoteIndex = jdkVersion.indexOf('"');
+ if (quoteIndex != -1) {
+ jdkVersion = jdkVersion.substring(quoteIndex + 1, jdkVersion.length() - 1);
+ }
+ }
+
+ return jdkVersion;
+ }
+}