/**
* 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;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLClassLoader;
import java.util.Date;
import java.util.Iterator;
import java.util.List;
import java.util.Properties;
import org.apache.maven.plugin.AbstractMojo;
import org.apache.maven.plugin.MojoExecutionException;
import org.apache.maven.plugins.annotations.Parameter;
import org.apache.maven.project.MavenProject;
import org.apache.velocity.Template;
import org.apache.velocity.VelocityContext;
import org.apache.velocity.app.VelocityEngine;
import org.apache.velocity.exception.VelocityException;
import org.apache.velocity.runtime.RuntimeConstants;
import org.apache.velocity.runtime.log.Log4JLogChute;
import org.apache.velocity.runtime.resource.loader.ClasspathResourceLoader;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* Base class for API based generation MOJOs.
*/
public abstract class AbstractGeneratorMojo extends AbstractMojo {
protected static final String PREFIX = "org.apache.camel.";
protected static final String OUT_PACKAGE = PREFIX + "component.internal";
protected static final String COMPONENT_PACKAGE = PREFIX + "component";
private static VelocityEngine engine;
private static ClassLoader projectClassLoader;
private static boolean sharedProjectState;
// used for velocity logging, to avoid creating velocity.log
protected final Logger log = LoggerFactory.getLogger(this.getClass());
@Parameter(defaultValue = OUT_PACKAGE)
protected String outPackage;
@Parameter(required = true, property = PREFIX + "scheme")
protected String scheme;
@Parameter(required = true, property = PREFIX + "componentName")
protected String componentName;
@Parameter(required = true, defaultValue = COMPONENT_PACKAGE)
protected String componentPackage;
@Parameter(required = true, defaultValue = "${project}", readonly = true)
protected MavenProject project;
protected AbstractGeneratorMojo() {
clearSharedProjectState();
}
public static void setSharedProjectState(boolean sharedProjectState) {
AbstractGeneratorMojo.sharedProjectState = sharedProjectState;
}
protected static void clearSharedProjectState() {
if (!sharedProjectState) {
projectClassLoader = null;
}
}
protected static VelocityEngine getEngine() {
if (engine == null) {
// initialize velocity to load resources from class loader and use Log4J
Properties velocityProperties = new Properties();
velocityProperties.setProperty(RuntimeConstants.RESOURCE_LOADER, "cloader");
velocityProperties.setProperty("cloader.resource.loader.class", ClasspathResourceLoader.class.getName());
velocityProperties.setProperty(RuntimeConstants.RUNTIME_LOG_LOGSYSTEM_CLASS, Log4JLogChute.class.getName());
final Logger velocityLogger = LoggerFactory.getLogger("org.apache.camel.maven.Velocity");
velocityProperties.setProperty(Log4JLogChute.RUNTIME_LOG_LOG4J_LOGGER, velocityLogger.getName());
engine = new VelocityEngine(velocityProperties);
engine.init();
}
return engine;
}
protected ClassLoader getProjectClassLoader() throws MojoExecutionException {
if (projectClassLoader == null) {
final List classpathElements;
try {
classpathElements = project.getTestClasspathElements();
} catch (org.apache.maven.artifact.DependencyResolutionRequiredException e) {
throw new MojoExecutionException(e.getMessage(), e);
}
final URL[] urls = new URL[classpathElements.size()];
int i = 0;
for (Iterator it = classpathElements.iterator(); it.hasNext(); i++) {
try {
urls[i] = new File((String) it.next()).toURI().toURL();
log.debug("Adding project path " + urls[i]);
} catch (MalformedURLException e) {
throw new MojoExecutionException(e.getMessage(), e);
}
}
final ClassLoader tccl = Thread.currentThread().getContextClassLoader();
projectClassLoader = new URLClassLoader(urls, tccl != null ? tccl : getClass().getClassLoader());
}
return projectClassLoader;
}
protected void mergeTemplate(VelocityContext context, File outFile, String templateName) throws MojoExecutionException {
// ensure parent directories exist
final File outDir = outFile.getParentFile();
if (!outDir.isDirectory() && !outDir.mkdirs()) {
throw new MojoExecutionException("Error creating directory " + outDir);
}
// add generated date
context.put("generatedDate", new Date().toString());
// add output package
context.put("packageName", outPackage);
context.put("newLine", "\n");
// load velocity template
final Template template = getEngine().getTemplate(templateName, "UTF-8");
// generate file
BufferedWriter writer = null;
try {
writer = new BufferedWriter(new FileWriter(outFile));
template.merge(context, writer);
} catch (IOException e) {
throw new MojoExecutionException(e.getMessage(), e);
} catch (VelocityException e) {
throw new MojoExecutionException(e.getMessage(), e);
} finally {
if (writer != null) {
try {
writer.close();
} catch (IOException ignore) { }
}
}
}
public static String getCanonicalName(Class<?> type) {
// remove java.lang prefix for default Java package
String canonicalName = type.getCanonicalName();
final int pkgEnd = canonicalName.lastIndexOf('.');
if (pkgEnd > 0 && canonicalName.substring(0, pkgEnd).equals("java.lang")) {
canonicalName = canonicalName.substring(pkgEnd + 1);
}
return canonicalName;
}
}