/**
* 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.FileFilter;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import org.apache.commons.io.FileUtils;
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.project.MavenProject;
import org.apache.maven.project.MavenProjectHelper;
import static org.apache.camel.maven.packaging.StringHelper.between;
/**
* Creates the Maven catalog for the Camel archetypes
*
* @goal generate-and-attach-archetype-catalog
*/
public class PackageArchetypeCatalogMojo extends AbstractMojo {
/**
* The maven project.
*
* @parameter property="project"
* @required
* @readonly
*/
protected MavenProject project;
/**
* The output directory for generated components file
*
* @parameter default-value="${project.build.directory}/classes/"
*/
protected File outDir;
/**
* The build directory
*
* @parameter default-value="${project.build.directory}"
*/
protected File projectBuildDir;
/**
* Maven ProjectHelper.
*
* @component
* @readonly
*/
private MavenProjectHelper projectHelper;
/**
* Execute goal.
*
* @throws org.apache.maven.plugin.MojoExecutionException execution of the main class or one of the
* threads it generated failed.
* @throws org.apache.maven.plugin.MojoFailureException something bad happened...
*/
public void execute() throws MojoExecutionException, MojoFailureException {
try {
generateArchetypeCatalog(getLog(), project, projectHelper, projectBuildDir, outDir);
} catch (IOException e) {
throw new MojoFailureException("Error generating archetype catalog due " + e.getMessage(), e);
}
}
public static void generateArchetypeCatalog(Log log, MavenProject project, MavenProjectHelper projectHelper, File projectBuildDir, File outDir) throws MojoExecutionException, IOException {
File rootDir = projectBuildDir.getParentFile();
log.info("Scanning for Camel Maven Archetypes from root directory " + rootDir);
// find all archetypes which are in the parent dir of the build dir
File[] dirs = rootDir.listFiles(new FileFilter() {
@Override
public boolean accept(File pathname) {
return pathname.getName().startsWith("camel-archetype") && pathname.isDirectory();
}
});
List<ArchetypeModel> models = new ArrayList<ArchetypeModel>();
for (File dir : dirs) {
File pom = new File(dir, "pom.xml");
if (!pom.exists() && !pom.isFile()) {
continue;
}
boolean parent = false;
ArchetypeModel model = new ArchetypeModel();
// just use a simple line by line text parser (no need for DOM) just to grab 4 lines of data
for (Object o : FileUtils.readLines(pom)) {
String line = o.toString();
// we only want to read version from parent
if (line.contains("<parent>")) {
parent = true;
continue;
}
if (line.contains("</parent>")) {
parent = false;
continue;
}
if (parent) {
// grab version from parent
String version = between(line, "<version>", "</version>");
if (version != null) {
model.setVersion(version);
}
continue;
}
String groupId = between(line, "<groupId>", "</groupId>");
String artifactId = between(line, "<artifactId>", "</artifactId>");
String description = between(line, "<description>", "</description>");
if (groupId != null && model.getGroupId() == null) {
model.setGroupId(groupId);
}
if (artifactId != null && model.getArtifactId() == null) {
model.setArtifactId(artifactId);
}
if (description != null && model.getDescription() == null) {
model.setDescription(description);
}
}
if (model.getGroupId() != null && model.getArtifactId() != null && model.getVersion() != null) {
models.add(model);
}
}
log.info("Found " + models.size() + " archetypes");
if (!models.isEmpty()) {
// make sure there is a dir
outDir.mkdirs();
File out = new File(outDir, "archetype-catalog.xml");
FileOutputStream fos = new FileOutputStream(out, false);
// write top
String top = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<archetype-catalog>\n <archetypes>";
fos.write(top.getBytes());
// write each archetype
for (ArchetypeModel model : models) {
fos.write("\n <archetype>".getBytes());
fos.write(("\n <groupId>" + model.getGroupId() + "</groupId>").getBytes());
fos.write(("\n <artifactId>" + model.getArtifactId() + "</artifactId>").getBytes());
fos.write(("\n <version>" + model.getVersion() + "</version>").getBytes());
if (model.getDescription() != null) {
fos.write(("\n <description>" + model.getDescription() + "</description>").getBytes());
}
fos.write("\n </archetype>".getBytes());
}
// write bottom
String bottom = "\n </archetypes>\n</archetype-catalog>\n";
fos.write(bottom.getBytes());
fos.close();
log.info("Saved archetype catalog to file " + out);
try {
if (projectHelper != null) {
log.info("Attaching archetype catalog to Maven project: " + project.getArtifactId());
List<String> includes = new ArrayList<String>();
includes.add("archetype-catalog.xml");
projectHelper.addResource(project, outDir.getPath(), includes, new ArrayList<String>());
projectHelper.attachArtifact(project, "xml", "archetype-catalog", out);
}
} catch (Exception e) {
throw new MojoExecutionException("Failed to attach artifact to Maven project. Reason: " + e, e);
}
}
}
private static class ArchetypeModel {
private String groupId;
private String artifactId;
private String version;
private String description;
public String getGroupId() {
return groupId;
}
public void setGroupId(String groupId) {
this.groupId = groupId;
}
public String getArtifactId() {
return artifactId;
}
public void setArtifactId(String artifactId) {
this.artifactId = artifactId;
}
public String getVersion() {
return version;
}
public void setVersion(String version) {
this.version = version;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
}
}