blob: 055c4dd6032a8045ab6831b7aaae86fc0d1acbee [file] [log] [blame]
/*
* 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.k.tooling.maven;
import java.io.File;
import java.io.InputStream;
import java.net.URL;
import java.net.URLClassLoader;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Stream;
import org.apache.maven.plugin.AbstractMojo;
import org.apache.maven.plugins.annotations.Parameter;
import org.apache.maven.project.MavenProject;
import org.jboss.jandex.AnnotationInstance;
import org.jboss.jandex.AnnotationTarget;
import org.jboss.jandex.AnnotationValue;
import org.jboss.jandex.ClassInfo;
import org.jboss.jandex.CompositeIndex;
import org.jboss.jandex.DotName;
import org.jboss.jandex.IndexReader;
import org.jboss.jandex.IndexView;
public abstract class GenerateYamlSupport extends AbstractMojo {
public static final DotName EXPRESSION_DEFINITION_CLASS = DotName.createSimple("org.apache.camel.model.language.ExpressionDefinition");
public static final DotName DATAFORMAT_DEFINITION_CLASS = DotName.createSimple("org.apache.camel.model.DataFormatDefinition");
public static final DotName XMLROOTELEMENT_ANNOTATION_CLASS = DotName.createSimple("javax.xml.bind.annotation.XmlRootElement");
public static final DotName YAML_STEP_DEFINITION_CLASS = DotName.createSimple("org.apache.camel.k.loader.yaml.model.Step$Definition");
public static final DotName YAML_STEP_PARSER_ANNOTATION = DotName.createSimple("org.apache.camel.k.annotation.yaml.YAMLStepParser");
public static final DotName YAML_STEP_DEFINITION_ANNOTATION = DotName.createSimple("org.apache.camel.k.annotation.yaml.YAMLNodeDefinition");
@Parameter(defaultValue = "${project}", readonly = true, required = true)
protected MavenProject project;
@Parameter(defaultValue = "${project.build.directory}/generated-sources/camel")
protected String output;
protected Map<String, Class<?>> definitions(DotName type) {
ClassLoader cl = getClassLoader();
Map<String, Class<?>> definitions = new HashMap<>();
IndexView view = getCompositeIndexer(cl);
for (ClassInfo ci: view.getAllKnownSubclasses(type)) {
AnnotationInstance instance = ci.classAnnotation(XMLROOTELEMENT_ANNOTATION_CLASS);
if (instance != null) {
AnnotationValue name = instance.value("name");
if (name != null) {
try {
definitions.put(name.asString(), cl.loadClass(ci.name().toString()));
} catch (ClassNotFoundException e) {
throw new RuntimeException(e);
}
}
}
}
return Collections.unmodifiableMap(definitions);
}
protected Stream<ClassInfo> implementors(DotName type) {
ClassLoader cl = getClassLoader();
IndexView view = getCompositeIndexer(cl);
return view.getAllKnownImplementors(type).stream();
}
protected Stream<ClassInfo> annotated(DotName type) {
ClassLoader cl = getClassLoader();
IndexView view = getCompositeIndexer(cl);
return view.getAnnotations(type).stream()
.map(AnnotationInstance::target)
.filter(t -> t.kind() == AnnotationTarget.Kind.CLASS)
.map(AnnotationTarget::asClass);
}
protected static IndexView getCompositeIndexer(ClassLoader classLoader) {
try {
Enumeration<URL> elements = classLoader.getResources("META-INF/jandex.idx");
List<IndexView> allIndex = new ArrayList<>();
Set<URL> locations = new HashSet<>();
for (Enumeration<URL> e = elements; e.hasMoreElements();) {
URL url = e.nextElement();
if (locations.add(url)) {
try (InputStream is = url.openStream()) {
allIndex.add(new IndexReader(is).read());
}
}
}
return CompositeIndex.create(allIndex);
} catch (Exception e) {
throw new RuntimeException(e);
}
}
protected ClassLoader getClassLoader() {
if (project == null) {
return getClass().getClassLoader();
}
try {
List<String> elements = new ArrayList<>();
elements.addAll(project.getCompileClasspathElements());
URL urls[] = new URL[elements.size()];
for (int i = 0; i < elements.size(); ++i) {
urls[i] = new File(elements.get(i)).toURI().toURL();
}
return new URLClassLoader(urls, this.getClass().getClassLoader());
} catch (Exception e) {
return this.getClass().getClassLoader();
}
}
}