org.apache.camel.maven.packaging.AbstractGeneratorMojo Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of camel-package-maven-plugin Show documentation
Show all versions of camel-package-maven-plugin Show documentation
Maven plugin to help package Camel components and plugins
The newest version!
/*
* 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.camel.maven.packaging;
import java.io.File;
import java.io.IOError;
import java.io.IOException;
import java.io.StringWriter;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.attribute.BasicFileAttributes;
import java.time.Duration;
import java.util.Collection;
import java.util.Collections;
import java.util.Date;
import java.util.HashSet;
import java.util.LinkedHashSet;
import java.util.Map;
import java.util.Properties;
import java.util.Set;
import java.util.TreeSet;
import java.util.concurrent.ConcurrentHashMap;
import java.util.function.Supplier;
import java.util.stream.Collectors;
import org.apache.camel.tooling.model.BaseOptionModel;
import org.apache.camel.tooling.util.FileUtil;
import org.apache.camel.tooling.util.PackageHelper;
import org.apache.camel.tooling.util.Strings;
import org.apache.maven.artifact.DependencyResolutionRequiredException;
import org.apache.maven.model.Resource;
import org.apache.maven.plugin.AbstractMojo;
import org.apache.maven.plugin.MojoExecutionException;
import org.apache.maven.plugin.MojoFailureException;
import org.apache.maven.plugin.logging.Log;
import org.apache.maven.plugins.annotations.Parameter;
import org.apache.maven.project.MavenProject;
import org.apache.maven.project.MavenProjectHelper;
import org.apache.velocity.Template;
import org.apache.velocity.VelocityContext;
import org.apache.velocity.runtime.RuntimeInstance;
import org.codehaus.plexus.build.BuildContext;
public abstract class AbstractGeneratorMojo extends AbstractMojo {
public static final String GENERATED_MSG = "Generated by camel build tools - do NOT edit this file!";
public static final String NL = "\n";
private static final Map> KNOWN_CLASSES_CACHE = new ConcurrentHashMap<>();
private static final RuntimeInstance VELOCITY = createVelocityRuntime();
private static final Map VELOCITY_TEMPLATES = new ConcurrentHashMap<>();
/**
* The maven project.
*/
@Parameter(property = "project", required = true, readonly = true)
protected MavenProject project;
/**
* Maven ProjectHelper.
*/
protected final MavenProjectHelper projectHelper;
/**
* build context to check changed files and mark them for refresh (used for m2e compatibility)
*/
protected final BuildContext buildContext;
private DynamicClassLoader projectClassLoader;
static {
KNOWN_CLASSES_CACHE.put("Byte", Byte.class);
KNOWN_CLASSES_CACHE.put("Boolean", Boolean.class);
KNOWN_CLASSES_CACHE.put("Date", Date.class);
KNOWN_CLASSES_CACHE.put("Double", Double.class);
KNOWN_CLASSES_CACHE.put("Duration", Duration.class);
KNOWN_CLASSES_CACHE.put("String", String.class);
KNOWN_CLASSES_CACHE.put("Integer", Integer.class);
KNOWN_CLASSES_CACHE.put("Long", Long.class);
KNOWN_CLASSES_CACHE.put("File", File.class);
KNOWN_CLASSES_CACHE.put("Object", Object.class);
KNOWN_CLASSES_CACHE.put("int", int.class);
KNOWN_CLASSES_CACHE.put("long", long.class);
KNOWN_CLASSES_CACHE.put("boolean", boolean.class);
}
protected AbstractGeneratorMojo(MavenProjectHelper projectHelper, BuildContext buildContext) {
this.projectHelper = projectHelper;
this.buildContext = buildContext;
}
public void execute(MavenProject project) throws MojoFailureException, MojoExecutionException {
this.project = project;
execute();
}
protected void addResourceDirectory(Path path) {
projectHelper.addResource(project, path.toString(), Collections.singletonList("**/*"), Collections.emptyList());
}
public void refresh(Path file) {
refresh(buildContext, file);
}
protected String velocity(String templatePath, Map ctx) {
VelocityContext context = new VelocityContext(ctx);
Template template = VELOCITY_TEMPLATES.computeIfAbsent(templatePath, VELOCITY::getTemplate);
StringWriter writer = new StringWriter();
template.merge(context, writer);
return writer.toString();
}
private static RuntimeInstance createVelocityRuntime() {
Properties props = new Properties();
props.setProperty("resource.loaders", "class");
props.setProperty("resource.loader.class.class", "org.apache.velocity.runtime.resource.loader.ClasspathResourceLoader");
RuntimeInstance velocity = new RuntimeInstance();
velocity.init(props);
return velocity;
}
protected boolean updateResource(Path dir, String fileName, String data) {
boolean updated = updateResource(buildContext, dir.resolve(fileName), data);
if (!fileName.endsWith(".java")) {
Path outputDir = Paths.get(project.getBuild().getOutputDirectory());
updated |= updateResource(buildContext, outputDir.resolve(fileName), data);
}
return updated;
}
protected String createProperties(String key, String val) {
return createProperties(project, key, val);
}
public static String createProperties(MavenProject project, String key, String val) {
StringBuilder properties = new StringBuilder(256);
properties.append("# ").append(GENERATED_MSG).append(NL);
properties.append(key).append("=").append(val).append(NL);
properties.append("groupId=").append(project.getGroupId()).append(NL);
properties.append("artifactId=").append(project.getArtifactId()).append(NL);
properties.append("version=").append(project.getVersion()).append(NL);
properties.append("projectName=").append(project.getName()).append(NL);
if (project.getDescription() != null) {
properties.append("projectDescription=").append(project.getDescription()).append(NL);
}
String annotations = project.getProperties().getProperty("annotations");
if (!Strings.isNullOrEmpty(annotations)) {
properties.append("annotations=").append(annotations).append(NL);
}
return properties.toString();
}
public static void refresh(BuildContext buildContext, Path file) {
if (buildContext != null) {
buildContext.refresh(file.toFile());
}
}
public static boolean updateResource(BuildContext buildContext, Path out, String data) {
try {
if (FileUtil.updateFile(out, data)) {
refresh(buildContext, out);
return true;
}
} catch (IOException e) {
throw new IOError(e);
}
return false;
}
public static boolean haveResourcesChanged(Log log, MavenProject project, BuildContext buildContext, String suffix) {
String baseDir = project.getBasedir().getAbsolutePath();
for (Resource r : project.getBuild().getResources()) {
File file = new File(r.getDirectory());
if (file.isAbsolute()) {
file = new File(r.getDirectory().substring(baseDir.length() + 1));
}
if (log.isDebugEnabled()) {
String path = file.getPath() + "/" + suffix;
log.debug("Checking if " + path + " (" + r.getDirectory() + "/" + suffix + ") has changed.");
}
if (buildContext.hasDelta(new File(file, suffix))) {
if (log.isDebugEnabled()) {
log.debug("Indeed " + suffix + " has changed.");
}
return true;
}
}
return false;
}
protected static Supplier cache(Supplier supplier) {
return new Supplier<>() {
T value;
@Override
public T get() {
if (value == null) {
value = supplier.get();
}
return value;
}
};
}
protected Class> loadClass(String loadClassName) {
return KNOWN_CLASSES_CACHE.computeIfAbsent(loadClassName, k -> doLoadClass(loadClassName));
}
private Class> doLoadClass(String loadClassName) {
Class> optionClass;
String org = loadClassName;
while (true) {
try {
optionClass = getProjectClassLoader().loadClass(loadClassName);
break;
} catch (ClassNotFoundException e) {
int dotIndex = loadClassName.lastIndexOf('.');
if (dotIndex == -1) {
if (getLog().isDebugEnabled()) {
getLog().debug("Failed to load class: " + loadClassName);
}
throw new NoClassDefFoundError(org);
} else {
loadClassName = loadClassName.substring(0, dotIndex) + "$" + loadClassName.substring(dotIndex + 1);
if (getLog().isDebugEnabled()) {
getLog().debug("Relocating previous class name for loading as: " + loadClassName);
}
}
}
}
return optionClass;
}
protected final ClassLoader getProjectClassLoader() {
if (projectClassLoader == null) {
try {
projectClassLoader = DynamicClassLoader.createDynamicClassLoader(project.getCompileClasspathElements());
} catch (DependencyResolutionRequiredException e) {
throw new RuntimeException("Unable to create project classloader", e);
}
}
return projectClassLoader;
}
protected boolean isJsonFile(Path p, BasicFileAttributes a) {
return a.isRegularFile() && p.toFile().getName().endsWith(PackageHelper.JSON_SUFIX);
}
@SuppressWarnings("unused") // use by velocity templates
public String canonicalClassName(String className) {
return Strings.canonicalClassName(className);
}
@SuppressWarnings("unused") // use by velocity templates
public String format(String fmt, Object... args) {
return String.format(fmt, args);
}
@SuppressWarnings("unused") // use by velocity templates
public TreeSet> newTreeSet() {
return new TreeSet<>();
}
@SuppressWarnings("unused") // use by velocity templates
public Set findConfigurations(Collection extends BaseOptionModel> options) {
final Set found = new HashSet<>();
return options.stream()
.filter(o -> o.getConfigurationField() != null)
.filter(o -> found.add(o.getConfigurationClass()))
.collect(Collectors.toCollection(LinkedHashSet::new));
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy