blob: 9f5c597d5d4e80c6a397a8b77783ddf3758ec950 [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you 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.apache.maven.plugins.jarsigner;
import java.io.File;
import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.apache.maven.plugin.Mojo;
import org.apache.maven.plugin.logging.Log;
import org.apache.maven.plugins.jarsigner.JarsignerSignMojo.WaitStrategy;
import org.apache.maven.project.MavenProject;
import org.apache.maven.shared.jarsigner.JarSigner;
import org.apache.maven.toolchain.ToolchainManager;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.sonatype.plexus.components.sec.dispatcher.SecDispatcher;
/**
* Creates and configures a Mojo instance to be used in testing.
*
* @param <T> The type of Mojo
*/
public class MojoTestCreator<T extends AbstractJarsignerMojo> {
private final Logger logger = LoggerFactory.getLogger(MojoTestCreator.class);
private final Class<T> clazz;
private final MavenProject project;
private final File projectDir;
private final JarSigner jarSigner;
private ToolchainManager toolchainManager;
private SecDispatcher securityDispatcher;
private WaitStrategy waitStrategy;
private Log log;
private List<Field> fields;
public MojoTestCreator(Class<T> clazz, MavenProject project, File projectDir, JarSigner jarSigner)
throws Exception {
this.clazz = clazz;
this.project = project;
this.projectDir = projectDir;
this.jarSigner = jarSigner;
securityDispatcher = str -> str; // Simple SecDispatcher that only returns parameter
fields = getAllFields(clazz);
}
public void setToolchainManager(ToolchainManager toolchainManager) {
this.toolchainManager = toolchainManager;
}
public void setSecDispatcher(SecDispatcher securityDispatcher) {
this.securityDispatcher = securityDispatcher;
}
public void setWaitStrategy(WaitStrategy waitStrategy) {
this.waitStrategy = waitStrategy;
}
public void setLog(Log log) {
this.log = log;
}
/**
* Creates and configures the Mojo instance.
* @param configuration user supplied configuration.
*/
public T configure(Map<String, String> configuration) throws Exception {
T mojo = clazz.getDeclaredConstructor().newInstance();
setDefaultValues(mojo);
setAttribute(mojo, "project", project);
setAttribute(mojo, "jarSigner", jarSigner);
setAttribute(mojo, "securityDispatcher", securityDispatcher);
if (toolchainManager != null) {
setAttribute(mojo, "toolchainManager", toolchainManager);
}
if (waitStrategy != null) {
((JarsignerSignMojo) mojo).setWaitStrategy(waitStrategy);
}
if (log != null) {
mojo.setLog(log);
}
for (Map.Entry<String, String> entry : configuration.entrySet()) {
Field field = getField(mojo, entry.getKey());
setFieldByStringValue(mojo, field, entry.getValue());
}
return mojo;
}
private void setFieldByStringValue(Object instance, Field field, String stringValue) throws Exception {
field.setAccessible(true);
Class<?> fieldType = field.getType();
if (fieldType.equals(String.class)) {
field.set(instance, stringValue);
} else if (fieldType.equals(int.class)) {
field.setInt(instance, Integer.parseInt(stringValue));
} else if (fieldType.equals(boolean.class)) {
field.setBoolean(instance, Boolean.parseBoolean(stringValue));
} else if (fieldType.equals(File.class)) {
field.set(instance, new File(stringValue));
} else if (fieldType.equals(String[].class)) {
String[] values = stringValue.split(",");
field.set(instance, values);
} else {
if (!stringValue.startsWith("${")) {
logger.warn(
"Not implemented support to set of field of type {} to value {}",
fieldType.getSimpleName(),
stringValue);
}
}
}
private Field getField(Object instance, String fieldName) {
return fields.stream()
.filter(f -> f.getName().equals(fieldName))
.findFirst()
.orElseThrow(() -> new RuntimeException("Could not find field " + fieldName + " in class "
+ instance.getClass().getName()));
}
private void setAttribute(Object instance, String fieldName, Object value) throws Exception {
Field field = getField(instance, fieldName);
field.setAccessible(true);
field.set(instance, value);
}
private void setDefaultValues(Mojo mojo) throws Exception {
Map<String, String> defaultConfiguration = PluginXmlParser.getMojoDefaultConfiguration(mojo.getClass());
for (String parameterName : defaultConfiguration.keySet()) {
String defaultValue = defaultConfiguration.get(parameterName);
defaultValue = substituteParameterValueVariables(defaultValue);
Field field = getField(mojo, parameterName);
setFieldByStringValue(mojo, field, defaultValue.toString());
}
}
private String substituteParameterValueVariables(String parameterValue) {
parameterValue = parameterValue.replaceAll(
Pattern.quote("${project.basedir}"), Matcher.quoteReplacement(projectDir.getPath()));
return parameterValue;
}
static List<Field> getAllFields(Class<?> clazz) {
List<Field> fields = new ArrayList<>();
Class<?> currentClazz = clazz;
while (currentClazz != null) {
fields.addAll(Arrays.asList(currentClazz.getDeclaredFields()));
currentClazz = currentClazz.getSuperclass();
}
return fields;
}
}