diff --git a/README.md b/README.md index f8630b2..e6ffc7f 100644 --- a/README.md +++ b/README.md @@ -31,13 +31,14 @@ This is a maven plugin that allows for developers and organizations to ban Maven com.inteligr8:ban-maven-plugin:[,1.0.0) log4j:log4j - org\.springframework.*::[,4.0.0.RELEASE) + org\.springframe.+::[,4.0.0.RELEASE) .... + https://domain:port/path/file ... @@ -61,5 +62,3 @@ The `version` element supports the standard Maven specification. You can match There is nothing stopping you from specifying two `artifact` elements with the exact same values. So you can ban multiple version ranges of the same artifact by using multiple `artifact` elements. If you *include* all versions by omitting the `version` element, you can still *exclude* (unban) certain versions, like `[1.2.17,)`. - -It is recommended that you look into [Maven Tiles](https://github.com/repaint-io/maven-tiles) so you can use a tile to define your banned artifacts and side load them into all your projects. \ No newline at end of file diff --git a/src/main/java/com/inteligr8/maven/ban/AbstractBanConfiguration.java b/src/main/java/com/inteligr8/maven/ban/AbstractBanConfiguration.java new file mode 100644 index 0000000..04744fc --- /dev/null +++ b/src/main/java/com/inteligr8/maven/ban/AbstractBanConfiguration.java @@ -0,0 +1,130 @@ +/* + * This program is free software: you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or (at your + * option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along + * with this program. If not, see . + */ +package com.inteligr8.maven.ban; + +import java.io.IOException; +import java.util.LinkedList; +import java.util.List; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +import org.apache.commons.lang3.StringUtils; +import org.apache.maven.artifact.versioning.InvalidVersionSpecificationException; +import org.apache.maven.artifact.versioning.VersionRange; +import org.apache.maven.plugin.MojoFailureException; +import org.codehaus.plexus.util.xml.Xpp3Dom; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.inteligr8.maven.model.ArtifactFilter; + +public class AbstractBanConfiguration implements BanConfiguration { + + private final Logger logger = LoggerFactory.getLogger(this.getClass()); + private final Pattern artifactPattern = Pattern.compile("^([^:]+):([^:]+)(:([^:]+))?$"); + private final Pattern notRegexPattern = Pattern.compile("^[A-Za-z0-9_\\.]*$"); + + private final List includeArtifacts = new LinkedList<>(); + private final List excludeArtifacts = new LinkedList<>(); + + public void init(Xpp3Dom rootDom) throws IOException, MojoFailureException { + if (rootDom == null) + return; + + Xpp3Dom importDom = rootDom.getChild("import"); + if (importDom != null) { + String url = StringUtils.trimToNull(importDom.getValue()); + BanConfigurationDownloader downloader = new BanConfigurationDownloader(url); + this.includeArtifacts.addAll(downloader.getIncludeArtifacts()); + this.excludeArtifacts.addAll(downloader.getExcludeArtifacts()); + } + + Xpp3Dom includesDom = rootDom.getChild("includes"); + if (includesDom != null) + this.includeArtifacts.addAll(this.parseArtifacts(includesDom)); + + Xpp3Dom excludesDom = rootDom.getChild("excludes"); + if (excludesDom != null) + this.excludeArtifacts.addAll(this.parseArtifacts(excludesDom)); + + this.logger.debug("Include artifacts: {}", this.includeArtifacts); + this.logger.debug("Exclude artifacts: {}", this.excludeArtifacts); + } + + public List getIncludeArtifacts() { + return this.includeArtifacts; + } + + public List getExcludeArtifacts() { + return this.excludeArtifacts; + } + + private List parseArtifacts(Xpp3Dom artifactsDom) { + List filters = new LinkedList<>(); + + for (Xpp3Dom artifactDom : artifactsDom.getChildren("artifact")) { + ArtifactFilter filter = new ArtifactFilter(); + String versionSpec = null; + if (artifactDom.getChildCount() == 0) { + Matcher matcher = this.artifactPattern.matcher(artifactDom.getValue()); + if (!matcher.matches()) { + this.logger.warn("The artifact format '{}' does not match the expected regular expression: {}; ignoring ...", artifactDom.getValue(), this.artifactPattern.pattern()); + continue; + } + + if (this.notRegexPattern.matcher(matcher.group(1)).matches()) { + filter.setGroupId(StringUtils.trimToNull(matcher.group(1))); + } else { + filter.setGroupIdRegex(StringUtils.trimToNull(matcher.group(1))); + } + + if (this.notRegexPattern.matcher(matcher.group(2)).matches()) { + filter.setArtifactId(StringUtils.trimToNull(matcher.group(2))); + } else { + filter.setArtifactIdRegex(StringUtils.trimToNull(matcher.group(2))); + } + + versionSpec = StringUtils.trimToNull(matcher.group(4)); + } else { + filter.setGroupId(this.getChildValue(artifactDom, "groupId")); + filter.setGroupIdRegex(this.getChildValue(artifactDom, "groupIdRegex")); + filter.setArtifactId(this.getChildValue(artifactDom, "artifactId")); + filter.setArtifactIdRegex(this.getChildValue(artifactDom, "artifactIdRegex")); + + versionSpec = this.getChildValue(artifactDom, "version"); + } + + if (versionSpec != null) { + try { + VersionRange versionRange = VersionRange.createFromVersionSpec(versionSpec); + filter.setVersionRange(versionRange); + } catch (InvalidVersionSpecificationException ivse) { + this.logger.warn("The artifact '{}' has an invalid version specification; the artifact element will be ignored: {}", ivse.getMessage()); + continue; + } + } + + filters.add(filter); + } + + return filters; + } + + private String getChildValue(Xpp3Dom dom, String child) { + Xpp3Dom childDom = dom.getChild(child); + return childDom == null ? null : StringUtils.trimToNull(childDom.getValue()); + } + +} diff --git a/src/main/java/com/inteligr8/maven/ban/BanConfiguration.java b/src/main/java/com/inteligr8/maven/ban/BanConfiguration.java new file mode 100644 index 0000000..b6d0b9f --- /dev/null +++ b/src/main/java/com/inteligr8/maven/ban/BanConfiguration.java @@ -0,0 +1,27 @@ +/* + * This program is free software: you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or (at your + * option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along + * with this program. If not, see . + */ +package com.inteligr8.maven.ban; + +import java.util.List; + +import com.inteligr8.maven.model.ArtifactFilter; + +public interface BanConfiguration { + + List getIncludeArtifacts(); + + List getExcludeArtifacts(); + +} diff --git a/src/main/java/com/inteligr8/maven/ban/BanConfigurationDownloader.java b/src/main/java/com/inteligr8/maven/ban/BanConfigurationDownloader.java new file mode 100644 index 0000000..65bfa82 --- /dev/null +++ b/src/main/java/com/inteligr8/maven/ban/BanConfigurationDownloader.java @@ -0,0 +1,54 @@ +/* + * This program is free software: you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or (at your + * option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along + * with this program. If not, see . + */ +package com.inteligr8.maven.ban; + +import java.io.BufferedInputStream; +import java.io.IOException; +import java.io.InputStream; +import java.net.URL; + +import org.apache.maven.plugin.MojoFailureException; +import org.codehaus.plexus.util.xml.Xpp3Dom; +import org.codehaus.plexus.util.xml.Xpp3DomBuilder; +import org.codehaus.plexus.util.xml.pull.XmlPullParserException; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class BanConfigurationDownloader extends AbstractBanConfiguration { + + private final Logger logger = LoggerFactory.getLogger(this.getClass()); + + public BanConfigurationDownloader(String url) throws IOException, MojoFailureException { + try { + Xpp3Dom rootDom = this.load(new URL(url)); + this.init(rootDom); + } catch (XmlPullParserException xppe) { + throw new MojoFailureException(xppe.getMessage(), xppe); + } + } + + private Xpp3Dom load(URL url) throws IOException, XmlPullParserException { + InputStream istream = url.openStream(); + BufferedInputStream bistream = new BufferedInputStream(istream, 16384); + try { + this.logger.debug("Downloading configuration: {}", url); + return Xpp3DomBuilder.build(bistream, "utf-8"); + } finally { + bistream.close(); + } + + } + +} diff --git a/src/main/java/com/inteligr8/maven/ban/BanConfigurationParser.java b/src/main/java/com/inteligr8/maven/ban/BanConfigurationParser.java index 8972f13..57ed2d0 100644 --- a/src/main/java/com/inteligr8/maven/ban/BanConfigurationParser.java +++ b/src/main/java/com/inteligr8/maven/ban/BanConfigurationParser.java @@ -14,118 +14,17 @@ */ package com.inteligr8.maven.ban; -import java.util.Collections; -import java.util.LinkedList; -import java.util.List; -import java.util.regex.Matcher; -import java.util.regex.Pattern; +import java.io.IOException; -import org.apache.commons.lang3.StringUtils; -import org.apache.maven.artifact.versioning.InvalidVersionSpecificationException; -import org.apache.maven.artifact.versioning.VersionRange; import org.apache.maven.model.Plugin; +import org.apache.maven.plugin.MojoFailureException; import org.codehaus.plexus.util.xml.Xpp3Dom; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import com.inteligr8.maven.model.ArtifactFilter; - -public class BanConfigurationParser { +public class BanConfigurationParser extends AbstractBanConfiguration { - private final Logger logger = LoggerFactory.getLogger(this.getClass()); - private final Pattern artifactPattern = Pattern.compile("^([^:]+):([^:]+)(:([^:]+))?$"); - private final Pattern notRegexPattern = Pattern.compile("^[A-Za-z0-9_\\.]*$"); - - private final List includeArtifacts; - private final List excludeArtifacts; - - public BanConfigurationParser(Plugin plugin) { + public BanConfigurationParser(Plugin plugin) throws IOException, MojoFailureException { Xpp3Dom rootDom = (Xpp3Dom) plugin.getConfiguration(); - if (rootDom == null) { - this.includeArtifacts = Collections.emptyList(); - this.excludeArtifacts = Collections.emptyList(); - return; - } - - Xpp3Dom includesDom = rootDom.getChild("includes"); - if (includesDom != null) { - this.includeArtifacts = this.parseArtifacts(includesDom); - this.logger.debug("Include artifacts: {}", this.includeArtifacts); - } else { - this.includeArtifacts = Collections.emptyList(); - } - - Xpp3Dom excludesDom = rootDom.getChild("excludes"); - if (excludesDom != null) { - this.excludeArtifacts = this.parseArtifacts(excludesDom); - this.logger.debug("Exclude artifacts: {}", this.excludeArtifacts); - } else { - this.excludeArtifacts = Collections.emptyList(); - } - } - - public List getIncludeArtifacts() { - return this.includeArtifacts; - } - - public List getExcludeArtifacts() { - return this.excludeArtifacts; - } - - private List parseArtifacts(Xpp3Dom artifactsDom) { - List filters = new LinkedList<>(); - - for (Xpp3Dom artifactDom : artifactsDom.getChildren("artifact")) { - ArtifactFilter filter = new ArtifactFilter(); - String versionSpec = null; - if (artifactDom.getChildCount() == 0) { - Matcher matcher = this.artifactPattern.matcher(artifactDom.getValue()); - if (!matcher.matches()) { - this.logger.warn("The artifact format '{}' does not match the expected regular expression: {}; ignoring ...", artifactDom.getValue(), this.artifactPattern.pattern()); - continue; - } - - if (this.notRegexPattern.matcher(matcher.group(1)).matches()) { - filter.setGroupId(StringUtils.trimToNull(matcher.group(1))); - } else { - filter.setGroupIdRegex(StringUtils.trimToNull(matcher.group(1))); - } - - if (this.notRegexPattern.matcher(matcher.group(2)).matches()) { - filter.setArtifactId(StringUtils.trimToNull(matcher.group(2))); - } else { - filter.setArtifactIdRegex(StringUtils.trimToNull(matcher.group(2))); - } - - versionSpec = StringUtils.trimToNull(matcher.group(4)); - } else { - filter.setGroupId(this.getChildValue(artifactDom, "groupId")); - filter.setGroupIdRegex(this.getChildValue(artifactDom, "groupIdRegex")); - filter.setArtifactId(this.getChildValue(artifactDom, "artifactId")); - filter.setArtifactIdRegex(this.getChildValue(artifactDom, "artifactIdRegex")); - - versionSpec = this.getChildValue(artifactDom, "version"); - } - - if (versionSpec != null) { - try { - VersionRange versionRange = VersionRange.createFromVersionSpec(versionSpec); - filter.setVersionRange(versionRange); - } catch (InvalidVersionSpecificationException ivse) { - this.logger.warn("The artifact '{}' has an invalid version specification; the artifact element will be ignored: {}", ivse.getMessage()); - continue; - } - } - - filters.add(filter); - } - - return filters; - } - - private String getChildValue(Xpp3Dom dom, String child) { - Xpp3Dom childDom = dom.getChild(child); - return childDom == null ? null : StringUtils.trimToNull(childDom.getValue()); + this.init(rootDom); } } diff --git a/src/main/java/com/inteligr8/maven/ban/BanExtension.java b/src/main/java/com/inteligr8/maven/ban/BanExtension.java index 65579dc..eed5550 100644 --- a/src/main/java/com/inteligr8/maven/ban/BanExtension.java +++ b/src/main/java/com/inteligr8/maven/ban/BanExtension.java @@ -14,6 +14,7 @@ */ package com.inteligr8.maven.ban; +import java.io.IOException; import java.util.LinkedList; import java.util.List; @@ -25,6 +26,7 @@ import org.apache.maven.AbstractMavenLifecycleParticipant; import org.apache.maven.MavenExecutionException; import org.apache.maven.execution.MavenSession; import org.apache.maven.model.Plugin; +import org.apache.maven.plugin.MojoFailureException; import org.apache.maven.plugin.PluginResolutionException; import org.apache.maven.plugin.internal.PluginDependenciesResolver; import org.apache.maven.project.DefaultDependencyResolutionRequest; @@ -59,7 +61,7 @@ public class BanExtension extends AbstractMavenLifecycleParticipant { @Override public void afterProjectsRead(MavenSession session) throws MavenExecutionException { MavenProject project = session.getCurrentProject(); - BanConfigurationParser config = this.getConfiguration(project); + BanConfiguration config = this.getConfiguration(project); if (config == null) return; @@ -104,7 +106,11 @@ public class BanExtension extends AbstractMavenLifecycleParticipant { this.logger.warn("The '{}' plugin must be defined with 'true'; ignoring plugin", plugin.getId()); return null; } else { - return new BanConfigurationParser(plugin); + try { + return new BanConfigurationParser(plugin); + } catch (IOException | MojoFailureException e) { + throw new MavenExecutionException(e.getMessage(), project.getFile()); + } } } diff --git a/src/main/java/com/inteligr8/maven/ban/PurgeRepoMojo.java b/src/main/java/com/inteligr8/maven/ban/PurgeRepoMojo.java index 75a21d5..a2b530b 100644 --- a/src/main/java/com/inteligr8/maven/ban/PurgeRepoMojo.java +++ b/src/main/java/com/inteligr8/maven/ban/PurgeRepoMojo.java @@ -159,7 +159,7 @@ public class PurgeRepoMojo extends AbstractMojo { } } - private BanConfigurationParser getConfiguration(MavenProject project) throws MojoFailureException { + private BanConfigurationParser getConfiguration(MavenProject project) throws MojoFailureException, IOException { Plugin plugin = project.getPlugin(BanExtension.THIS_PLUGIN_KEY); if (plugin == null) throw new MojoFailureException("The plugin is executing but it cannot be found");