GenerateInspectionsMojo.java
/*
* Copyright (C) 2017 Red Hat, Inc.
*
* 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 io.atlasmap.maven;
import java.io.File;
import java.io.IOException;
import java.net.URL;
import java.net.URLClassLoader;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import org.apache.maven.plugin.MojoExecutionException;
import org.apache.maven.plugin.MojoFailureException;
import org.apache.maven.plugins.annotations.Mojo;
import org.apache.maven.plugins.annotations.Parameter;
import io.atlasmap.core.DefaultAtlasConversionService;
import io.atlasmap.java.inspect.ClassInspectionService;
import io.atlasmap.java.v2.JavaClass;
import io.atlasmap.json.inspect.JsonInspectionService;
import io.atlasmap.json.v2.JsonDocument;
import io.atlasmap.v2.CollectionType;
import io.atlasmap.xml.inspect.XmlInspectionService;
import io.atlasmap.xml.v2.XmlDocument;
@Mojo(name = "generate-inspections")
public class GenerateInspectionsMojo extends AbstractAtlasMapMojo {
public static final String DEFAULT_OUTPUT_FILE_PREFIX = "atlasmap-inspection";
/**
* A list of {@code <groupId>:<artifactId>[:<extension>[:<classifier>]]:<version>} of
* the artifacts to resolve.
*/
@Parameter
private List<String> artifacts;
/**
* The class name that should be inspected.
*/
@Parameter(property = "className")
private String className;
/**
* The collection type that should be inspected.
*/
@Parameter(property = "collectionType")
private String collectionType;
/**
* The class name that should be inspected.
*/
@Parameter(property = "collectionClassName")
private String collectionClassName;
/**
* Allows you to configure the plugin with: <code>
*
* <configuration>
* <inspections>
* <inspection>
* <artifacts>
* <artifact>io.atlasmap:atlas-java-generateInspection-test:1.1</artifact>
* </artifacts>
* <className>org.some.JavaClass</className>
* </inspection>
* <inspection>
* <artifacts>
* <artifact>io.atlasmap:other:1.1</artifact>
* </artifacts>
* <classNames>
* <className>org.some.JavaClass1</className>
* <className>org.some.JavaClass2</className>
* </classNames>
* </inspection>
* <inspection>
* <fileName>src/test/resources</fileName>
* <inspectionType>SCHEMA</inspectionType>
* </inspection>
* </inspections>
* </configuration>
*
* </code>
*/
@Parameter()
private List<Inspection> inspections;
public enum InspectionType {
SCHEMA, INSTANCE
}
public static class Inspection {
private List<String> artifacts;
private String className;
private String collectionType;
private String collectionClassName;
private List<String> classNames;
private String fileName;
private InspectionType inspectionType;
public String getClassName() {
return className;
}
public List<String> getClassNames() {
return classNames;
}
public void setClassName(String className) {
this.className = className;
}
public void setClassNames(List<String> classNames) {
this.classNames = classNames;
}
public String getCollectionType() {
return collectionType;
}
public void setCollectionType(String collectionType) {
this.collectionType = collectionType;
}
public String getCollectionClassName() {
return collectionClassName;
}
public void setCollectionClassName(String collectionClassName) {
this.collectionClassName = collectionClassName;
}
public List<String> getArtifacts() {
return artifacts;
}
public void setArtifacts(List<String> artifacts) {
this.artifacts = artifacts;
}
public String getFileName() {
return this.fileName;
}
public void setFileName(String fileName) {
this.fileName = fileName;
}
public InspectionType getInspectionType() {
return this.inspectionType;
}
public void setInspectionType(InspectionType inspectionType) {
this.inspectionType = inspectionType;
}
}
public void execute() throws MojoExecutionException, MojoFailureException {
if (getOutputDir() != null) {
getOutputDir().mkdirs();
}
CollectionType collectionType = CollectionType.NONE;
if (this.collectionType != null) {
collectionType = CollectionType.valueOf(this.collectionType);
}
if (this.artifacts != null && this.className != null) {
generateJavaInspection(this.artifacts, Arrays.asList(className), collectionType, collectionClassName);
}
if (inspections != null) {
for (Inspection inspection : inspections) {
ArrayList<String> classNames = new ArrayList<>();
if (inspection.classNames != null) {
classNames.addAll(inspection.classNames);
} else if (inspection.className != null) {
classNames.add(inspection.className);
} else {
generateFileInspection(inspection);
}
collectionType = CollectionType.NONE;
if (inspection.collectionType != null) {
collectionType = CollectionType.valueOf(inspection.collectionType);
}
generateJavaInspection(inspection.artifacts, classNames, collectionType, inspection.collectionClassName);
}
}
}
private void generateJavaInspection(List<String> artifacts, Collection<String> classNames,
CollectionType collectionType, String collectionClassName) throws MojoFailureException, MojoExecutionException {
List<URL> urls = artifacts == null ? Collections.emptyList() : resolveClasspath(artifacts);
ClassLoader origTccl = Thread.currentThread().getContextClassLoader();
for (String className : classNames) {
Class<?> clazz = null;
JavaClass c = null;
// Not even this plugin will be available on this new URLClassLoader
try (URLClassLoader loader = new URLClassLoader(urls.toArray(new URL[urls.size()]), origTccl)) {
clazz = loader.loadClass(className);
ClassInspectionService classInspectionService = new ClassInspectionService();
classInspectionService.setConversionService(DefaultAtlasConversionService.getInstance());
c = classInspectionService.inspectClass(loader, clazz, collectionType, collectionClassName);
} catch (ClassNotFoundException | IOException e) {
throw new MojoExecutionException(e.getMessage(), e);
}
writeToJsonFile(DEFAULT_OUTPUT_FILE_PREFIX + "-" + className, c);
}
}
private void generateFileInspection(Inspection inspection) throws MojoFailureException {
File file = new File(inspection.fileName);
if (!file.exists()) {
getLog().warn(String.format("Ignoring '%s'", inspection.fileName));
return;
}
if (file.isDirectory()) {
for (File child : file.listFiles()) {
if (!child.exists() || child.isDirectory()) {
getLog().warn(String.format("Ignoring '%s'", child.getAbsolutePath()));
continue;
}
if (child.getName().toLowerCase().endsWith(".json")) {
if (inspection.inspectionType == InspectionType.INSTANCE) {
generateJsonInstanceInspection(child.getAbsolutePath());
} else {
// schema inspection by default
generateJsonSchemaInspection(child.getAbsolutePath());
}
} else if (child.getName().toLowerCase().endsWith(".xsd")) {
generateXmlSchemaInspection(child.getAbsolutePath());
} else if (child.getName().toLowerCase().endsWith(".xml")) {
if (inspection.inspectionType == InspectionType.SCHEMA) {
// In case it's SchemaSet - XML contains XSDs. InspectionType.SCHEMA have to be specified.
generateXmlSchemaInspection(child.getAbsolutePath());
} else {
generateXmlInstanceInspection(child.getAbsolutePath());
}
} else {
getLog().warn(String.format("Ignoring unsupported file type '%s'", child.getAbsolutePath()));
continue;
}
}
return;
}
if (file.getName().toLowerCase().endsWith(".json")) {
if (inspection.inspectionType == InspectionType.INSTANCE) {
generateJsonInstanceInspection(file.getAbsolutePath());
} else {
// schema inspection by default
generateJsonSchemaInspection(file.getAbsolutePath());
}
} else if (file.getName().toLowerCase().endsWith(".xsd")) {
generateXmlSchemaInspection(file.getAbsolutePath());
} else if (file.getName().toLowerCase().endsWith(".xml")) {
if (inspection.inspectionType == InspectionType.SCHEMA) {
// In case it's SchemaSet - XML contains XSDs. InspectionType.SCHEMA have to be specified.
generateXmlSchemaInspection(file.getAbsolutePath());
} else {
generateXmlInstanceInspection(file.getAbsolutePath());
}
} else {
throw new MojoFailureException(String.format("Inspection type '%s' is not supported", inspection.getClass().getName()));
}
}
private void generateJsonSchemaInspection(String fileName) throws MojoFailureException {
try {
Path path = Paths.get(fileName);
String schema = new String(Files.readAllBytes(path));
JsonDocument d = new JsonInspectionService().inspectJsonSchema(schema);
String name = path.getFileName().toString();
String outputName = name.substring(0, name.length() - 5);
writeToJsonFile(DEFAULT_OUTPUT_FILE_PREFIX + "-" + outputName, d);
} catch (Exception e) {
throw new MojoFailureException(e.getMessage(), e);
}
}
private void generateJsonInstanceInspection(String fileName) throws MojoFailureException {
try {
Path path = Paths.get(fileName);
String schema = new String(Files.readAllBytes(path));
JsonDocument d = new JsonInspectionService().inspectJsonDocument(schema);
String name = path.getFileName().toString();
String outputName = name.substring(0, name.length() - 5);
writeToJsonFile(DEFAULT_OUTPUT_FILE_PREFIX + "-" + outputName, d);
} catch (Exception e) {
throw new MojoFailureException(e.getMessage(), e);
}
}
private void generateXmlSchemaInspection(String fileName) throws MojoFailureException {
try {
File f = new File(fileName);
XmlDocument d = new XmlInspectionService().inspectSchema(f);
String outputName = f.getName().substring(0, f.getName().length() - 4);
writeToJsonFile(DEFAULT_OUTPUT_FILE_PREFIX + "-" + outputName, d);
} catch (Exception e) {
throw new MojoFailureException(e.getMessage(), e);
}
}
private void generateXmlInstanceInspection(String fileName) throws MojoFailureException {
try {
File f = new File(fileName);
XmlDocument d = new XmlInspectionService().inspectXmlDocument(f);
String outputName = f.getName().substring(0, f.getName().length() - 4);
writeToJsonFile(DEFAULT_OUTPUT_FILE_PREFIX + "-" + outputName, d);
} catch (Exception e) {
throw new MojoFailureException(e.getMessage(), e);
}
}
public List<String> getArtifacts() {
return artifacts;
}
public void setArtifacts(List<String> artifacts) {
this.artifacts = artifacts;
}
public String getClassName() {
return className;
}
public void setClassName(String className) {
this.className = className;
}
public List<Inspection> getInspections() {
return inspections;
}
public void setInspections(List<Inspection> inspections) {
this.inspections = inspections;
}
}