
org.kantega.reststop.maven.CreatePluginMojo Maven / Gradle / Ivy
The newest version!
/*
* Copyright 2018 Kantega AS
*
* Licensed 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.kantega.reststop.maven;
import org.apache.maven.model.Model;
import org.apache.maven.model.Plugin;
import org.apache.maven.model.io.xpp3.MavenXpp3Reader;
import org.apache.maven.plugin.MojoExecutionException;
import org.apache.maven.plugin.MojoFailureException;
import org.apache.maven.plugins.annotations.Component;
import org.apache.maven.plugins.annotations.Mojo;
import org.apache.maven.plugins.annotations.Parameter;
import org.apache.maven.project.MavenProject;
import org.apache.maven.shared.invoker.DefaultInvocationRequest;
import org.apache.maven.shared.invoker.InvocationRequest;
import org.apache.maven.shared.invoker.Invoker;
import org.apache.maven.shared.invoker.MavenInvocationException;
import org.codehaus.plexus.util.xml.Xpp3Dom;
import org.codehaus.plexus.util.xml.pull.XmlPullParserException;
import org.eclipse.aether.RepositorySystem;
import org.eclipse.aether.RepositorySystemSession;
import org.eclipse.aether.repository.RemoteRepository;
import org.eclipse.jgit.api.Git;
import org.eclipse.jgit.api.errors.GitAPIException;
import org.xml.sax.SAXException;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.TransformerException;
import javax.xml.xpath.XPathExpressionException;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.regex.Pattern;
import static java.util.Arrays.asList;
/**
* Creates a new Reststop plugins in an already created Reststop Maven project.
*/
@Mojo(name = "create-plugin", requiresProject = true, aggregator = true)
public class CreatePluginMojo extends AbstractCreateMojo {
@Parameter(defaultValue = "${project.groupId}", property = "groupId")
private String groupId;
@Parameter(defaultValue = "${project.version}", property = "version")
private String version;
@Parameter(defaultValue = "${project.artifactId}", property = "artifactId")
private String artifactId;
@Parameter(property = "name")
private String pluginName;
@Parameter(property = "package")
private String pack;
@Parameter(defaultValue = "${project}", readonly = true)
private MavenProject mavenProject;
@Component
private Invoker invoker;
@Component
protected RepositorySystem repoSystem;
@Parameter(defaultValue ="${repositorySystemSession}" ,readonly = true)
protected RepositorySystemSession repoSession;
@Parameter(defaultValue = "${project.remoteProjectRepositories}")
protected List remoteRepos;
@Override
public void execute() throws MojoExecutionException, MojoFailureException {
String rootArtifactId;
File basedir = mavenProject.getBasedir();
try {
File pluginsDir;
File appOrWebappDir;
if (basedir.getName().equalsIgnoreCase("plugins")) {
rootArtifactId = mavenProject.getParent().getArtifactId();
pluginsDir = basedir;
appOrWebappDir = getAppOrWebapp(basedir.getParentFile());
} else if (basedir.getName().equalsIgnoreCase("webapp") ||
basedir.getName().equalsIgnoreCase("app")) {
rootArtifactId = mavenProject.getParent().getArtifactId();
pluginsDir = new File(basedir.getParent(), "plugins");
if (!pluginsDir.exists()) {
pluginsDir.mkdirs();
}
appOrWebappDir = basedir;
} else if (basedir.getName().equalsIgnoreCase(artifactId)) {
rootArtifactId = artifactId;
pluginsDir = new File(basedir, "plugins");
if (!pluginsDir.exists()) {
pluginsDir.mkdirs();
}
appOrWebappDir = getAppOrWebapp(basedir);
} else {
//TODO: Check parent until we find root of project.
//basedir.getParentFile();
throw new MojoFailureException("Could not find a proper Reststop directory structure, please use create goal.");
}
if (!appOrWebappDir.exists()) {
throw new MojoFailureException("Could not find the webapp directory, resulting in an improper Reststop directory structure, please use create goal.");
}
if(rootArtifactId.endsWith("-parent")) {
rootArtifactId = rootArtifactId.substring(0, rootArtifactId.indexOf("-parent"));
}
Map options = getOptions();
pack = options.get("package").toLowerCase();
pluginName = options.get("name").toLowerCase();
File pluginDir = new File(pluginsDir, pluginName);
if (pluginDir.exists()) {
throw new MojoFailureException(String.format("Plugin %s in %s already exists.", pluginName, pluginsDir));
}
File pluginPomFile = new File(pluginDir, "pom.xml");
Map tokens = new HashMap<>();
tokens.put("${groupId}", groupId);
tokens.put("${name}", pluginName);
tokens.put("${rootArtifactId}", rootArtifactId);
tokens.put("${version}", mavenProject.getVersion());
createMavenModule(tokens, getClass().getResourceAsStream("dist/template-newplugin-pom.xml"), pluginPomFile);
new File(pluginDir, "src/main/resources").mkdirs();
new File(pluginDir, "src/test/resources").mkdirs();
File sourceDir = new File(pluginDir, "src/main/java");
sourceDir.mkdirs();
File pluginClassFile = createPluginClass(pluginName, sourceDir, pack);
pomAddModule(new File(pluginsDir, "pom.xml"), pluginName);
pomAddPluginToReststop(new File(appOrWebappDir, "pom.xml"), groupId, rootArtifactId + "-" + pluginName, "${project.version}");
addNewFilesToGit(pluginsDir, pluginPomFile, pluginClassFile);
getLog().info(String.format("Successfully generated new plugin '%s' in %s.", pluginName, pluginDir));
if(false) {
Resolver resolver = new Resolver(repoSystem, repoSession, remoteRepos, getLog());
Deployer deployer = new Deployer(resolver, invoker, getLog());
deployer.cleanInstall(pluginDir);
deployer.deployPlugin(groupId, rootArtifactId + "-" + pluginName, mavenProject.getVersion(), pluginDir);
}
} catch (IOException e) {
throw new MojoExecutionException(e.getMessage(), e);
}
}
private File getAppOrWebapp(File basedir) {
File webapp = new File(basedir, "webapp");
if(webapp.exists()) {
return webapp;
}
return new File(basedir, "app");
}
private void addNewFilesToGit(File pluginsDir, File pluginPomFile, File pluginClassFile) throws IOException {
File gitDir = new File(new File(pluginsDir.getParent()), ".git");
if (gitDir.exists()) {
File workDir = new File(gitDir.getParent());
Git git = null;
try {
git = Git.open(workDir);
git.add().addFilepattern(getRelativeTo(pluginPomFile, workDir)).call();
git.add().addFilepattern(getRelativeTo(pluginClassFile, workDir)).call();
} catch (GitAPIException e) {
// ignore
} finally {
if (git != null) {
git.close();
}
}
}
}
private String getRelativeTo(File file, File base) {
return base.toURI().relativize(file.toURI()).getPath();
}
private void pomAddModule(File pom, String name) throws MojoExecutionException {
Model model = getModelFromPom(pom);
if (!model.getModules().contains(name)) {
MavenPomUtils pomUtils = new MavenPomUtils();
try {
pomUtils.addModule(pom, pom, name);
} catch (IOException | ParserConfigurationException | TransformerException | SAXException e) {
throw new MojoExecutionException(String.format("Could not add module %s to pom file %s", name, pom), e);
}
}
}
private void pomAddPluginToReststop(File pom, String groupId, String artifactId, String version) throws MojoExecutionException {
Model model = getModelFromPom(pom);
boolean present = false;
for (Plugin plugin : model.getBuild().getPlugins()) {
if (plugin.getArtifactId().equalsIgnoreCase("reststop-maven-plugin")) {
Xpp3Dom configuration = (Xpp3Dom) plugin.getConfiguration();
Xpp3Dom plugins = configuration.getChild("plugins");
Xpp3Dom[] children = plugins.getChildren();
if (children.length != 0) {
for (Xpp3Dom p : children) {
if (p.getChild("artifactId").getValue().equalsIgnoreCase(artifactId)) {
present = true;
}
}
if (!present) {
MavenPomUtils pomUtils = new MavenPomUtils();
try {
pomUtils.addPluginToReststop(pom, pom, groupId, artifactId, version);
} catch (IOException | ParserConfigurationException | TransformerException | SAXException | XPathExpressionException e) {
throw new MojoExecutionException(String.format("Could not add plugin %s:%s:%s to pom file %s", groupId, artifactId, version, pom), e);
}
}
}
}
}
}
private Model getModelFromPom(File pom) throws MojoExecutionException {
MavenXpp3Reader reader = new MavenXpp3Reader();
Model model;
try {
model = reader.read(new FileInputStream(pom));
} catch (IOException e) {
throw new MojoExecutionException(String.format("Could not read file: %s", pom), e);
} catch (XmlPullParserException e) {
throw new MojoExecutionException(String.format("Error parsing XML in file: %s: ", pom), e);
}
return model;
}
private Map getOptions() {
Map values = new LinkedHashMap<>();
do {
boolean onlyParameterValues = true;
if (pluginName == null) {
onlyParameterValues = false;
readValue(values, "name", "example");
} else {
values.put("name", pluginName);
}
if (pack == null) {
onlyParameterValues = false;
String defaultPackage = groupId + "." + removeSpecialCharactersAndCapitalize(values.get("name")).toLowerCase();
String pack;
for (; ; ) {
pack = readLineWithDefault("package", defaultPackage).trim();
if (pack.isEmpty()) pack = defaultPackage;
Pattern p = Pattern.compile("^[a-zA-Z_\\$][\\w\\$]*(?:\\.[a-zA-Z_\\$][\\w\\$]*)*$");
if (p.matcher(pack).matches()) {
break;
}
}
values.put("package", pack);
} else {
values.put("package", pack);
}
if(onlyParameterValues) return values;
System.out.println();
System.out.println("Please confirm configuration:");
for (String option : values.keySet()) {
System.console().printf(" %s = '%s'\n", option, values.get(option));
}
} while (!System.console().readLine(" Y: ").equalsIgnoreCase("y"));
return values;
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy