
io.zenwave360.generator.Plugin Maven / Gradle / Ivy
package io.zenwave360.generator;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.stream.Collectors;
import org.apache.commons.lang3.reflect.FieldUtils;
import org.reflections.Reflections;
import io.zenwave360.generator.doc.DocumentedOption;
import io.zenwave360.generator.doc.DocumentedPlugin;
import io.zenwave360.generator.utils.NamingUtils;
public class Plugin {
@DocumentedOption(description = "Spec file to parse", required = true)
public String specFile;
@DocumentedOption(description = "Target folder for generated output", required = false)
public String targetFolder;
private List chain;
private Map options = new HashMap<>();
private ClassLoader projectClassLoader;
public static Plugin of(String pluginConfigAsString) throws Exception {
if (pluginConfigAsString != null) {
if (pluginConfigAsString.contains(".")) {
return (Plugin) Plugin.class.getClassLoader().loadClass(pluginConfigAsString).getDeclaredConstructor().newInstance();
}
String simpleClassName = NamingUtils.asJavaTypeName(pluginConfigAsString);
var allConfigClasses = new Reflections("io.zenwave360.generator.plugins").getSubTypesOf(Plugin.class);
Optional> pluginClass = allConfigClasses.stream().filter(c -> matchesClassName(c, pluginConfigAsString, simpleClassName)).findFirst();
if (pluginClass.isPresent()) {
return pluginClass.get().getDeclaredConstructor().newInstance();
}
}
return new Plugin();
}
private static boolean matchesClassName(Class c, String pluginConfigAsString, String simpleClassName) {
DocumentedPlugin documentedPlugin = (DocumentedPlugin) c.getAnnotation(DocumentedPlugin.class);
if (documentedPlugin != null && pluginConfigAsString.contentEquals(documentedPlugin.shortCode())) {
return true;
}
return c.getSimpleName().matches(simpleClassName + "(Configuration){0,1}$");
}
public T processOptions() {
return (T) this;
}
public Plugin withSpecFile(String specFile) {
this.specFile = specFile != null? specFile.replaceAll("\\\\", "/") : specFile;
this.options.put("specFile", this.specFile);
return this;
}
public Plugin withTargetFolder(String targetFolder) {
if (targetFolder != null) {
this.targetFolder = targetFolder;
this.options.put("targetFolder", targetFolder);
}
return this;
}
public Plugin withProjectClassLoader(ClassLoader projectClassLoader) {
this.projectClassLoader = projectClassLoader;
return this;
}
public Plugin withOption(String name, Object value) {
String lastPath = name;
Map nestedTempObject = options;
String[] paths = name.split("\\.");
for (int i = 0; i < paths.length; i++) {
lastPath = paths[i];
if (!nestedTempObject.containsKey(lastPath)) {
nestedTempObject.put(paths[i], new HashMap<>());
}
if (i < paths.length - 1) {
nestedTempObject = (Map) nestedTempObject.get(lastPath);
}
}
if(value instanceof String && ((String) value).contains(",")) {
value = Arrays.asList(((String) value).split(","));
}
nestedTempObject.put(lastPath, value);
try {
if (FieldUtils.getField(this.getClass(), name) != null) {
FieldUtils.writeField(this, name, value);
}
} catch (IllegalAccessException e) {
throw new RuntimeException(e);
}
return this;
}
public Plugin withOptions(Map options) {
options.entrySet().forEach(o -> withOption(o.getKey(), o.getValue()));
return this;
}
public Plugin withChain(Class... processorClasses) {
if (processorClasses != null) {
chain = new ArrayList<>(List.of(processorClasses));
}
return this;
}
public Plugin withChain(String... processorClasses) {
if (processorClasses != null) {
chain = Arrays.stream(processorClasses).map(c -> {
try {
return getClass().getClassLoader().loadClass(c);
} catch (ClassNotFoundException e) {
throw new RuntimeException(e);
}
}).collect(Collectors.toList());
}
return this;
}
public Plugin removeFromChain(Class... processorClasses) {
Arrays.stream(processorClasses).forEach(processorClass -> chain.remove(processorClass));
return this;
}
public Plugin replaceInChain(Class current, Class replacement) {
chain.replaceAll(chainedProcessor -> chainedProcessor.equals(current) ? replacement : chainedProcessor);
return this;
}
public Plugin addAfterInChain(Class pivot, Class newProcessor) {
int index = chain.indexOf(pivot) + 1;
if (index == -1) {
chain.add(newProcessor);
} else {
chain.add(index, newProcessor);
}
return this;
}
public Plugin addBeforeInChain(Class pivot, Class newProcessor) {
int index = chain.indexOf(pivot);
if (index >= 0) {
chain.add(index, newProcessor);
} else {
chain.add(newProcessor);
}
return this;
}
public String getSpecFile() {
return specFile;
}
public void setSpecFile(String specFile) {
this.specFile = specFile;
}
public List getChain() {
return chain;
}
public void setChain(List chain) {
this.chain = chain;
}
public Map getOptions() {
return options;
}
public void setOptions(Map options) {
this.options = options;
}
public String getTargetFolder() {
return targetFolder;
}
public void setTargetFolder(String targetFolder) {
this.targetFolder = targetFolder;
}
public ClassLoader getProjectClassLoader() {
return this.projectClassLoader;
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy