@@ -32,7 +32,7 @@ import java.util.Set; | |||
/** | |||
* Base class for Sonar-plugin-packaging related tasks. | |||
* | |||
* | |||
* @author Evgeny Mandrikov | |||
*/ | |||
public abstract class AbstractSonarPluginMojo extends AbstractMojo { | |||
@@ -42,7 +42,7 @@ public abstract class AbstractSonarPluginMojo extends AbstractMojo { | |||
/** | |||
* The Maven project. | |||
* | |||
* | |||
* @parameter expression="${project}" | |||
* @required | |||
* @readonly | |||
@@ -51,7 +51,7 @@ public abstract class AbstractSonarPluginMojo extends AbstractMojo { | |||
/** | |||
* Directory containing the generated JAR. | |||
* | |||
* | |||
* @parameter expression="${project.build.directory}" | |||
* @required | |||
*/ | |||
@@ -59,7 +59,7 @@ public abstract class AbstractSonarPluginMojo extends AbstractMojo { | |||
/** | |||
* Directory containing the classes and resource files that should be packaged into the JAR. | |||
* | |||
* | |||
* @parameter expression="${project.build.outputDirectory}" | |||
* @required | |||
*/ | |||
@@ -67,7 +67,7 @@ public abstract class AbstractSonarPluginMojo extends AbstractMojo { | |||
/** | |||
* The directory where the app is built. | |||
* | |||
* | |||
* @parameter expression="${project.build.directory}/${project.build.finalName}" | |||
* @required | |||
*/ | |||
@@ -75,7 +75,7 @@ public abstract class AbstractSonarPluginMojo extends AbstractMojo { | |||
/** | |||
* Name of the generated JAR. | |||
* | |||
* | |||
* @parameter alias="jarName" expression="${jar.finalName}" default-value="${project.build.finalName}" | |||
* @required | |||
*/ | |||
@@ -83,7 +83,7 @@ public abstract class AbstractSonarPluginMojo extends AbstractMojo { | |||
/** | |||
* Classifier to add to the artifact generated. If given, the artifact will be an attachment instead. | |||
* | |||
* | |||
* @parameter | |||
*/ | |||
private String classifier; | |||
@@ -95,7 +95,7 @@ public abstract class AbstractSonarPluginMojo extends AbstractMojo { | |||
/** | |||
* Plugin key. | |||
* | |||
* | |||
* @parameter expression="${sonar.pluginKey}" default-value="${project.artifactId}" | |||
*/ | |||
private String pluginKey; | |||
@@ -107,7 +107,7 @@ public abstract class AbstractSonarPluginMojo extends AbstractMojo { | |||
/** | |||
* Name of plugin class. | |||
* | |||
* | |||
* @parameter expression="${sonar.pluginClass}" | |||
* @required | |||
*/ | |||
@@ -133,6 +133,12 @@ public abstract class AbstractSonarPluginMojo extends AbstractMojo { | |||
*/ | |||
private String pluginIssueTrackerUrl; | |||
/** | |||
* @parameter | |||
* @since 0.3 | |||
*/ | |||
private boolean useChildFirstClassLoader = false; | |||
/** | |||
* @parameter expression="${sonar.skipDependenciesPackaging}" | |||
*/ | |||
@@ -193,11 +199,15 @@ public abstract class AbstractSonarPluginMojo extends AbstractMojo { | |||
return pluginIssueTrackerUrl; | |||
} | |||
public boolean isUseChildFirstClassLoader() { | |||
return useChildFirstClassLoader; | |||
} | |||
protected boolean isSkipDependenciesPackaging() { | |||
return skipDependenciesPackaging; | |||
} | |||
@SuppressWarnings({"unchecked"}) | |||
@SuppressWarnings( { "unchecked" }) | |||
protected Set<Artifact> getDependencyArtifacts() { | |||
return getProject().getDependencyArtifacts(); | |||
} | |||
@@ -212,7 +222,7 @@ public abstract class AbstractSonarPluginMojo extends AbstractMojo { | |||
return result; | |||
} | |||
@SuppressWarnings({"unchecked"}) | |||
@SuppressWarnings( { "unchecked" }) | |||
protected Set<Artifact> getIncludedArtifacts() { | |||
Set<Artifact> result = new HashSet<Artifact>(); | |||
Set<Artifact> artifacts = getProject().getArtifacts(); |
@@ -43,11 +43,15 @@ import org.sonar.updatecenter.common.PluginManifest; | |||
import java.io.File; | |||
import java.io.IOException; | |||
import java.util.*; | |||
import java.util.ArrayList; | |||
import java.util.Date; | |||
import java.util.HashSet; | |||
import java.util.List; | |||
import java.util.Set; | |||
/** | |||
* Build a Sonar Plugin from the current project. | |||
* | |||
* | |||
* @author Evgeny Mandrikov | |||
* @goal sonar-plugin | |||
* @phase package | |||
@@ -57,13 +61,13 @@ import java.util.*; | |||
*/ | |||
public class SonarPluginMojo extends AbstractSonarPluginMojo { | |||
private static final String LIB_DIR = "META-INF/lib/"; | |||
private static final String[] DEFAULT_EXCLUDES = new String[]{"**/package.html"}; | |||
private static final String[] DEFAULT_INCLUDES = new String[]{"**/**"}; | |||
private static final String[] DEFAULT_EXCLUDES = new String[] { "**/package.html" }; | |||
private static final String[] DEFAULT_INCLUDES = new String[] { "**/**" }; | |||
/** | |||
* List of files to include. Specified as fileset patterns which are relative to the input directory whose contents | |||
* is being packaged into the JAR. | |||
* | |||
* | |||
* @parameter | |||
*/ | |||
private String[] includes; | |||
@@ -71,14 +75,14 @@ public class SonarPluginMojo extends AbstractSonarPluginMojo { | |||
/** | |||
* List of files to exclude. Specified as fileset patterns which are relative to the input directory whose contents | |||
* is being packaged into the JAR. | |||
* | |||
* | |||
* @parameter | |||
*/ | |||
private String[] excludes; | |||
/** | |||
* The Jar archiver. | |||
* | |||
* | |||
* @component role="org.codehaus.plexus.archiver.Archiver" role-hint="jar" | |||
*/ | |||
protected JarArchiver jarArchiver; | |||
@@ -86,7 +90,7 @@ public class SonarPluginMojo extends AbstractSonarPluginMojo { | |||
/** | |||
* The archive configuration to use. | |||
* See <a href="http://maven.apache.org/shared/maven-archiver/index.html">Maven Archiver Reference</a>. | |||
* | |||
* | |||
* @parameter | |||
*/ | |||
private MavenArchiveConfiguration archive = new MavenArchiveConfiguration(); | |||
@@ -100,7 +104,7 @@ public class SonarPluginMojo extends AbstractSonarPluginMojo { | |||
/** | |||
* The artifact repository to use. | |||
* | |||
* | |||
* @parameter expression="${localRepository}" | |||
* @required | |||
* @readonly | |||
@@ -109,7 +113,7 @@ public class SonarPluginMojo extends AbstractSonarPluginMojo { | |||
/** | |||
* The artifact factory to use. | |||
* | |||
* | |||
* @component | |||
* @required | |||
* @readonly | |||
@@ -118,7 +122,7 @@ public class SonarPluginMojo extends AbstractSonarPluginMojo { | |||
/** | |||
* The artifact metadata source to use. | |||
* | |||
* | |||
* @component | |||
* @required | |||
* @readonly | |||
@@ -127,7 +131,7 @@ public class SonarPluginMojo extends AbstractSonarPluginMojo { | |||
/** | |||
* The artifact collector to use. | |||
* | |||
* | |||
* @component | |||
* @required | |||
* @readonly | |||
@@ -177,12 +181,16 @@ public class SonarPluginMojo extends AbstractSonarPluginMojo { | |||
addManifestProperty("Build date", PluginManifest.BUILD_DATE, FormatUtils.toString(new Date(), true)); | |||
getLog().info("-------------------------------------------------------"); | |||
if (isUseChildFirstClassLoader()) { | |||
archive.addManifestEntry(PluginManifest.USE_CHILD_FIRST_CLASSLOADER, true); | |||
} | |||
if (isSkipDependenciesPackaging()) { | |||
getLog().info("Skip packaging of dependencies"); | |||
} else { | |||
List<String> libs = copyDependencies(); | |||
if (!libs.isEmpty()) { | |||
if ( !libs.isEmpty()) { | |||
archiver.getArchiver().addDirectory(getAppDirectory(), getIncludes(), getExcludes()); | |||
archive.addManifestEntry(PluginManifest.DEPENDENCIES, StringUtils.join(libs, " ")); | |||
} | |||
@@ -228,9 +236,8 @@ public class SonarPluginMojo extends AbstractSonarPluginMojo { | |||
return null; | |||
} | |||
private void checkPluginClass() throws MojoExecutionException { | |||
if (!new File(getClassesDirectory(), getPluginClass().replace('.', '/') + ".class").exists()) { | |||
if ( !new File(getClassesDirectory(), getPluginClass().replace('.', '/') + ".class").exists()) { | |||
throw new MojoExecutionException("Error assembling Sonar-plugin: Plugin-Class '" + getPluginClass() + "' not found"); | |||
} | |||
} | |||
@@ -244,7 +251,6 @@ public class SonarPluginMojo extends AbstractSonarPluginMojo { | |||
return new File(basedir, finalName + classifier + ".jar"); | |||
} | |||
private List<String> copyDependencies() throws IOException, DependencyTreeBuilderException { | |||
List<String> ids = new ArrayList<String>(); | |||
List<String> libs = new ArrayList<String>(); | |||
@@ -257,13 +263,13 @@ public class SonarPluginMojo extends AbstractSonarPluginMojo { | |||
ids.add(artifact.getDependencyConflictId()); | |||
} | |||
if (!ids.isEmpty()) { | |||
if ( !ids.isEmpty()) { | |||
getLog().info(getMessage("Following dependencies are packaged in the plugin:", ids)); | |||
getLog().info(new StringBuilder() | |||
.append("See following page for more details about plugin dependencies:\n") | |||
.append("\n\thttp://docs.codehaus.org/display/SONAR/Coding+a+plugin\n") | |||
.toString() | |||
); | |||
); | |||
} | |||
return libs; | |||
} | |||
@@ -300,7 +306,6 @@ public class SonarPluginMojo extends AbstractSonarPluginMojo { | |||
return false; | |||
} | |||
private Set<Artifact> getSonarProvidedArtifacts() throws DependencyTreeBuilderException { | |||
Set<Artifact> result = new HashSet<Artifact>(); | |||
ArtifactFilter artifactFilter = new ScopeArtifactFilter(Artifact.SCOPE_RUNTIME); | |||
@@ -322,7 +327,7 @@ public class SonarPluginMojo extends AbstractSonarPluginMojo { | |||
sonarArtifacts.add(dependency.getArtifact()); | |||
} | |||
if (!Artifact.SCOPE_TEST.equals(dependency.getArtifact().getScope())) { | |||
if ( !Artifact.SCOPE_TEST.equals(dependency.getArtifact().getScope())) { | |||
for (Object childDep : dependency.getChildren()) { | |||
searchForSonarProvidedArtifacts((DependencyNode) childDep, sonarArtifacts, isProvidedBySonar); | |||
} |
@@ -19,6 +19,8 @@ | |||
*/ | |||
package org.sonar.updatecenter.common; | |||
import static org.sonar.updatecenter.common.FormatUtils.toDate; | |||
import org.apache.commons.lang.StringUtils; | |||
import org.apache.commons.lang.builder.ReflectionToStringBuilder; | |||
@@ -29,11 +31,9 @@ import java.util.jar.Attributes; | |||
import java.util.jar.JarFile; | |||
import java.util.jar.Manifest; | |||
import static org.sonar.updatecenter.common.FormatUtils.toDate; | |||
/** | |||
* This class loads Sonar plugin metadata from JAR manifest | |||
* | |||
* This class loads Sonar plugin metadata from JAR manifest. | |||
* | |||
* @since 2.2 | |||
*/ | |||
public final class PluginManifest { | |||
@@ -53,6 +53,11 @@ public final class PluginManifest { | |||
public static final String BUILD_DATE = "Build-Date"; | |||
public static final String ISSUE_TRACKER_URL = "Plugin-IssueTrackerUrl"; | |||
/** | |||
* @since 0.3 | |||
*/ | |||
public static final String USE_CHILD_FIRST_CLASSLOADER = "Plugin-ChildFirstClassLoader"; | |||
private String key; | |||
private String name; | |||
private String mainClass; | |||
@@ -67,7 +72,7 @@ public final class PluginManifest { | |||
private String termsConditionsUrl; | |||
private Date buildDate; | |||
private String issueTrackerUrl; | |||
private boolean useChildFirstClassLoader = false; | |||
/** | |||
* Load the manifest from a JAR file. | |||
@@ -109,6 +114,7 @@ public final class PluginManifest { | |||
this.sonarVersion = attributes.getValue(SONAR_VERSION); | |||
this.issueTrackerUrl = attributes.getValue(ISSUE_TRACKER_URL); | |||
this.buildDate = toDate(attributes.getValue(BUILD_DATE), true); | |||
this.useChildFirstClassLoader = StringUtils.equalsIgnoreCase(attributes.getValue(USE_CHILD_FIRST_CLASSLOADER), "true"); | |||
String deps = attributes.getValue(DEPENDENCIES); | |||
this.dependencies = StringUtils.split(StringUtils.defaultString(deps), ' '); | |||
@@ -240,6 +246,15 @@ public final class PluginManifest { | |||
return this; | |||
} | |||
public boolean isUseChildFirstClassLoader() { | |||
return useChildFirstClassLoader; | |||
} | |||
public PluginManifest setUseChildFirstClassLoader(boolean useChildFirstClassLoader) { | |||
this.useChildFirstClassLoader = useChildFirstClassLoader; | |||
return this; | |||
} | |||
@Override | |||
public String toString() { | |||
return new ReflectionToStringBuilder(this).toString(); |
@@ -19,6 +19,11 @@ | |||
*/ | |||
package org.sonar.updatecenter.common; | |||
import static org.hamcrest.core.Is.is; | |||
import static org.hamcrest.core.IsNull.nullValue; | |||
import static org.hamcrest.number.OrderingComparisons.greaterThan; | |||
import static org.junit.Assert.assertThat; | |||
import org.junit.Test; | |||
import java.io.File; | |||
@@ -26,11 +31,6 @@ import java.io.IOException; | |||
import java.net.URISyntaxException; | |||
import java.net.URL; | |||
import static org.hamcrest.core.Is.is; | |||
import static org.hamcrest.core.IsNull.nullValue; | |||
import static org.hamcrest.number.OrderingComparisons.greaterThan; | |||
import static org.junit.Assert.assertThat; | |||
public class PluginManifestTest { | |||
@Test | |||
@@ -42,6 +42,7 @@ public class PluginManifestTest { | |||
assertThat(manifest.getName(), is("Checkstyle")); | |||
assertThat(manifest.getMainClass(), is("org.sonar.plugins.checkstyle.CheckstylePlugin")); | |||
assertThat(manifest.getVersion().length(), greaterThan(1)); | |||
assertThat(manifest.isUseChildFirstClassLoader(), is(false)); | |||
assertThat(manifest.getDependencies().length, is(4)); | |||
assertThat(manifest.getDependencies()[0], is("META-INF/lib/antlr-2.7.6.jar")); | |||
} | |||
@@ -54,6 +55,7 @@ public class PluginManifestTest { | |||
assertThat(manifest.getKey(), nullValue()); | |||
assertThat(manifest.getName(), nullValue()); | |||
assertThat(manifest.getMainClass(), is("org.sonar.plugins.checkstyle.CheckstylePlugin")); | |||
assertThat(manifest.isUseChildFirstClassLoader(), is(false)); | |||
assertThat(manifest.getDependencies().length, is(0)); | |||
} | |||
} |