Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 0 additions & 5 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -124,11 +124,6 @@ OF THE POSSIBILITY OF SUCH DAMAGE.
<version>1.7.0</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>commons-collections</groupId>
<artifactId>commons-collections</artifactId>
<version>3.2.2</version>
</dependency>
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
Expand Down
5 changes: 0 additions & 5 deletions qulice-maven-plugin/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -133,11 +133,6 @@ OF THE POSSIBILITY OF SUCH DAMAGE.
<artifactId>commons-io</artifactId>
<!-- version from parent -->
</dependency>
<dependency>
<groupId>commons-collections</groupId>
<artifactId>commons-collections</artifactId>
<!-- version from parent -->
</dependency>
<dependency>
<groupId>com.jcabi</groupId>
<artifactId>jcabi-log</artifactId>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,13 +30,12 @@
*/
package com.qulice.maven;

import com.qulice.maven.transformer.DuplicateFinderExclude;
import com.qulice.maven.transformer.Exclude;
import com.qulice.spi.ValidationException;
import java.util.Arrays;
import java.util.Collection;
import java.util.LinkedList;
import java.util.Properties;
import java.util.stream.Collectors;
import org.apache.commons.collections.CollectionUtils;

/**
* Validate with maven-duplicate-finder-plugin.
Expand All @@ -46,48 +45,39 @@
* Resource can be presented as a regular expression with that symbol, can cause some problem.
*/
public final class DuplicateFinderValidator implements MavenValidator {
/**
* Duplicatefinder constant.
*/
private static final String DUPLICATEFINDER = "duplicatefinder";

@Override
public void validate(final MavenEnvironment env)
throws ValidationException {
final String prefix = "duplicatefinder";
if (!env.exclude(prefix, "")) {
if (!env.exclude(DuplicateFinderValidator.DUPLICATEFINDER, "")) {
final Properties props = new Properties();
props.put("failBuildInCaseOfConflict", "true");
props.put("checkTestClasspath", "false");
props.put("useResultFile", "false");
props.put(
"ignoredResourcePatterns",
CollectionUtils.union(
env.excludes(prefix).stream()
.filter(s -> !s.contains(":"))
.collect(Collectors.toList()),
Arrays.asList("META-INF/.*", "module-info.class")
)
);
final Collection<Properties> ignres = new LinkedList<>();
final Collection<Properties> deps = new LinkedList<>();
for (final String sdep : env.excludes(prefix)) {
final String[] parts = sdep.split(":");
if (parts.length < 2) {
continue;
for (final String sdep : env.excludes(DuplicateFinderValidator.DUPLICATEFINDER)) {
final Exclude<Properties, Properties> exclude =
new DuplicateFinderExclude(DuplicateFinderValidator.DUPLICATEFINDER, sdep);
final Collection<Properties> excl = exclude.dependencies();
if (!excl.isEmpty()) {
deps.addAll(excl);
}
final Properties main = new Properties();
final Properties prop = new Properties();
prop.put("groupId", parts[0]);
prop.put("artifactId", parts[1]);
if (parts.length > 2) {
prop.put("version", parts[2]);
final Collection<Properties> res = exclude.resources();
if (!res.isEmpty()) {
ignres.addAll(excl);
}
main.put("dependency", prop);
deps.add(main);
}
props.put("ignoredDependencies", deps);
props.put("ignoredResourcePatterns", ignres);
env.executor().execute(
"org.basepom.maven:duplicate-finder-maven-plugin:2.0.1",
"check",
props
);
}
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -31,10 +31,10 @@
package com.qulice.maven;

import com.jcabi.log.Logger;
import com.qulice.maven.transformer.PlexusConfigurationToXpp3Dom;
import com.qulice.maven.transformer.PropertiesToXpp3Dom;
import com.qulice.spi.ValidationException;
import java.util.Collection;
import java.util.LinkedList;
import java.util.Map;
import java.util.Properties;
import org.apache.maven.execution.MavenSession;
import org.apache.maven.model.Plugin;
Expand All @@ -50,8 +50,6 @@
import org.apache.maven.plugin.PluginResolutionException;
import org.apache.maven.plugin.descriptor.MojoDescriptor;
import org.apache.maven.reporting.exec.DefaultMavenPluginManagerHelper;
import org.codehaus.plexus.configuration.PlexusConfiguration;
import org.codehaus.plexus.configuration.PlexusConfigurationException;
import org.codehaus.plexus.util.xml.Xpp3Dom;

/**
Expand Down Expand Up @@ -101,6 +99,7 @@ public MojoExecutor(final MavenPluginManager mngr,
* @param config The configuration to set
* @throws ValidationException If something is wrong inside
*/
@SuppressWarnings("PMD.UseProperClassLoader")
public void execute(final String coords, final String goal,
final Properties config) throws ValidationException {
final Plugin plugin = new Plugin();
Expand All @@ -123,19 +122,22 @@ public void execute(final String coords, final String goal,
throw new IllegalStateException("Can't setup realm", ex);
}
final Xpp3Dom xpp = Xpp3Dom.mergeXpp3Dom(
this.toXppDom(config, "configuration"),
this.toXppDom(descriptor.getMojoConfiguration())
new PropertiesToXpp3Dom(config, "configuration").transform(),
new PlexusConfigurationToXpp3Dom(descriptor.getMojoConfiguration()).transform()
);
final MojoExecution execution = new MojoExecution(descriptor, xpp);
final Mojo mojo = this.mojo(execution);
final ClassLoader cloader = Thread.currentThread().getContextClassLoader();
try {
Logger.info(this, "Calling %s:%s...", coords, goal);
Thread.currentThread().setContextClassLoader(mojo.getClass().getClassLoader());
mojo.execute();
} catch (final MojoExecutionException ex) {
throw new IllegalArgumentException(ex);
} catch (final MojoFailureException ex) {
throw new ValidationException(ex);
} finally {
Thread.currentThread().setContextClassLoader(cloader);
this.manager.releaseMojo(mojo, execution);
}
}
Expand Down Expand Up @@ -179,87 +181,4 @@ private Mojo mojo(final MojoExecution execution) {
}
return mojo;
}

/**
* Recuresively convert Properties to Xpp3Dom.
* @param config The config to convert
* @param name High-level name of it
* @return The Xpp3Dom document
* @see #execute(String,String,Properties)
* @checkstyle ExecutableStatementCountCheck (100 lines)
*/
@SuppressWarnings({"PMD.AvoidInstantiatingObjectsInLoops", "PMD.CognitiveComplexity"})
private Xpp3Dom toXppDom(final Properties config, final String name) {
final Xpp3Dom xpp = new Xpp3Dom(name);
for (final Map.Entry<?, ?> entry : config.entrySet()) {
if (entry.getValue() instanceof String) {
final Xpp3Dom child = new Xpp3Dom(entry.getKey().toString());
child.setValue(config.getProperty(entry.getKey().toString()));
xpp.addChild(child);
} else if (entry.getValue() instanceof String[]) {
final Xpp3Dom child = new Xpp3Dom(entry.getKey().toString());
for (final String val : String[].class.cast(entry.getValue())) {
final Xpp3Dom row = new Xpp3Dom(entry.getKey().toString());
row.setValue(val);
child.addChild(row);
}
xpp.addChild(child);
} else if (entry.getValue() instanceof Collection) {
final Xpp3Dom child = new Xpp3Dom(entry.getKey().toString());
for (final Object val : Collection.class.cast(entry.getValue())) {
if (val instanceof Properties) {
child.addChild(
this.toXppDom(
Properties.class.cast(val),
entry.getKey().toString()
).getChild(0)
);
} else if (val != null) {
final Xpp3Dom row = new Xpp3Dom(entry.getKey().toString());
row.setValue(val.toString());
child.addChild(row);
}
}
xpp.addChild(child);
} else if (entry.getValue() instanceof Properties) {
xpp.addChild(
this.toXppDom(
Properties.class.cast(entry.getValue()),
entry.getKey().toString()
)
);
} else {
throw new IllegalArgumentException(
String.format(
"Invalid properties value at '%s'",
entry.getKey().toString()
)
);
}
}
return xpp;
}

/**
* Recursively convert PLEXUS config to Xpp3Dom.
* @param config The config to convert
* @return The Xpp3Dom document
* @see #execute(String,String,Properties)
*/
private Xpp3Dom toXppDom(final PlexusConfiguration config) {
final Xpp3Dom result = new Xpp3Dom(config.getName());
result.setValue(config.getValue(null));
for (final String name : config.getAttributeNames()) {
try {
result.setAttribute(name, config.getAttribute(name));
} catch (final PlexusConfigurationException ex) {
throw new IllegalArgumentException(ex);
}
}
for (final PlexusConfiguration child : config.getChildren()) {
result.addChild(this.toXppDom(child));
}
return result;
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,125 @@
/*
* Copyright (c) 2011-2024 Qulice.com
*
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met: 1) Redistributions of source code must retain the above
* copyright notice, this list of conditions and the following
* disclaimer. 2) Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials provided
* with the distribution. 3) Neither the name of the Qulice.com nor
* the names of its contributors may be used to endorse or promote
* products derived from this software without specific prior written
* permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT
* NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
* THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package com.qulice.maven.transformer;

import java.util.LinkedList;
import java.util.List;
import java.util.Properties;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
* Implementation of exclude model for DuplicateFinder plugin.
*
* @since 0.23.1
*/
public final class DuplicateFinderExclude implements Exclude<Properties, Properties> {
/**
* Pattern for parsing ignore list.
*/
private final Pattern pattern;

/**
* Configuration string.
* - duplicatefinder:about.html
* - duplicatefinder:org.eclipse.sisu:org.eclipse.sisu.plexus:0.0.0.M5
* - duplicatefinder:org.codehaus.groovy.ast.expr.RegexExpression
* - duplicatefinder:org.eclipse.sisu:org.eclipse.sisu.plexus:0.0.0.M5
* |xml-apis:xml-apis:1.0.0|about.html
* - duplicatefinder:org.eclipse.sisu:org.eclipse.sisu.plexus:0.0.0.M5
* |xml-apis:xml-apis:1.0.0|org.w3c.dom.UserDataHandler
* See https://github.com/tpc2/qulice/issues/152#issuecomment-39028953
* and https://github.com/teamed/qulice/issues/250 for details
*/
private final String excludes;

/**
* Ctor.
* @param predicate Predicate for plugin.
* @param excl String with exclude from config.
*/
public DuplicateFinderExclude(final String predicate, final String excl) {
this.pattern = Pattern.compile(
String.format(
"(%s:)|(%s)|(?<res>[\\w-\\.&&[^\\|]]+)",
predicate,
"(?<gr>[\\w\\.-]+):(?<art>[\\w\\.-]+):(?<ver>[\\w\\.-]+)"
)
);
this.excludes = excl;
}

@Override
public List<Properties> dependencies() {
final Matcher matcher = this.pattern.matcher(this.excludes);
final List<Properties> deps = new LinkedList<>();
while (matcher.find()) {
final String group = matcher.group("gr");
final String artifact = matcher.group("art");
final String version = matcher.group("ver");
if (!empty(group) && !empty(artifact) && !empty(version)) {
final Properties main = new Properties();
final Properties prop = new Properties();
prop.put("groupId", group);
prop.put("artifactId", artifact);
prop.put("version", version);
main.put("dependency", prop);
deps.add(main);
}
}
return deps;
}

@Override
public List<Properties> resources() {
final Matcher matcher = this.pattern.matcher(this.excludes);
final List<Properties> res = new LinkedList<>();
while (matcher.find()) {
final String resource = matcher.group("res");
if (!empty(resource)) {
final Properties prop = new Properties();
prop.put("ignoredResourcePattern", resource);
res.add(prop);
}
}
return res;
}

/**
* Check string.
*
* @param value String for check.
* @return True for not empty string.
*/
private static boolean empty(final String value) {
return value == null || value.isBlank();
}
}
Loading