blob: 249d6cd8fa839b68da26e17fc46b616c520daebc [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.geronimo.arthur.spi;
import java.lang.annotation.Annotation;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.Collection;
import java.util.Objects;
import java.util.Optional;
import java.util.function.BiPredicate;
import java.util.function.Predicate;
import java.util.stream.Stream;
import org.apache.geronimo.arthur.spi.model.ClassReflectionModel;
import org.apache.geronimo.arthur.spi.model.DynamicProxyModel;
import org.apache.geronimo.arthur.spi.model.ResourceBundleModel;
import org.apache.geronimo.arthur.spi.model.ResourceModel;
/**
* Enable to enrich the build with some metadata.
*/
public interface ArthurExtension {
/**
* @return the priority of this extension (natural order sorting).
*/
default int order() {
return 0;
}
/**
* @param context current build context.
*/
void execute(Context context);
/**
* Enables to mutate the native image command generation and to manipulate current "context" (classloader).
*/
interface Context {
/**
* Find classes based on annotation on classes.
* @param annotation the marker annotation to look for.
* @param <T> the annotation type.
* @return the list of classes with this annotation.
*/
<T extends Annotation> Collection<Class<?>> findAnnotatedClasses(Class<T> annotation);
/**
* Simular to {@link #findAnnotatedClasses(Class)} but at method level.
* @param annotation the marker annotation to look for.
* @param <T> the annotation type.
* @return the list of methods with this annotation.
*/
<T extends Annotation> Collection<Method> findAnnotatedMethods(Class<T> annotation);
/**
* Simular to {@link #findAnnotatedMethods(Class)} but at field level.
* @param annotation the marker annotation to look for.
* @param <T> the annotation type.
* @return the list of methods with this annotation.
*/
<T extends Annotation> Collection<Field> findAnnotatedFields(Class<T> annotation);
/**
* Find subclasses and implementation of a parent.
*
* @param parent the parent class to use as marker.
* @param <T> the type of the parent.
* @return the list of children classes.
*/
<T> Collection<Class<? extends T>> findImplementations(Class<T> parent);
/**
* Adds a reflection model in the context, if it already exists it is replaced.
* @param classReflectionModel the instance to register.
*/
void register(ClassReflectionModel classReflectionModel);
/**
* Adds a resource model in the context, if it already exists it is replaced.
* @param resourceModel the instance to register.
*/
void register(ResourceModel resourceModel);
/**
* Adds a bundle model in the context, if it already exists it is replaced.
* @param resourceModel the instance to register.
*/
void register(ResourceBundleModel resourceModel);
/**
* Adds a proxy model in the context, if it already exists it is replaced.
* @param dynamicProxyModel the instance to register.
*/
void register(DynamicProxyModel dynamicProxyModel);
/**
* Enables java security in the native image.
*/
void enableAllSecurityServices();
/**
* Includes charsets in the native image.
*/
void enableAllCharsets();
/**
* Includes resource bundle (directly from the CLI since graal has some bugs on that as of today).
*/
void includeResourceBundle(String name);
/**
* Forces classes to be initialized during the build and not at run time.
* @param classes classes to initialize.
*/
void initializeAtBuildTime(String... classes);
/**
* Forces classes to be initialized during the run only, not the build.
* @param classes classes to initialize.
*/
void initializeAtRunTime(String... classes);
/**
* Retrieve a context property, used to configured an extension.
* @param key the key to read.
* @return the value or null if missing.
*/
String getProperty(String key);
/**
* Sets a property in the context, it can be used if extensions are chained for example.
* @param key the property key.
* @param value the value to set for the specified key.
*/
void setProperty(String key, String value);
/**
* Add specific native image option to the command line. Useful for custom graal extension options.
* @param option the command line option to set.
*/
void addNativeImageOption(String option);
/**
* Loads a class in current context.
* @param name the class name to load.
* @return the loaded class.
* @throws IllegalStateException if the class can't be found.
*/
Class<?> loadClass(String name);
/**
* Enable to add to native-image execution custom classes generated before the native-image execution.
* It can be common for proxies and classes created at runtime normally.
*
* @param name the class name.
* @param bytecode the class bytecode.
*/
void registerGeneratedClass(final String name, final byte[] bytecode);
/**
* Creates a stream of all classes (class, super classes and interfaces) for the specified class.
* @param from the class to look the hierarchy for.
* @return the class hierarchy.
*/
Stream<Class<?>> findHierarchy(Class<?> from);
/**
* Creates a predicate from the specified context property (key). It uses the value as a comma separated list.
* @param property the key to read the property from in the context.
* @param type matching type.
* @return an optional predicate for the specified property.
*/
Optional<Predicate<String>> createPredicate(String property, PredicateType type);
/**
* Use a base property suffixed with "includes" and "excludes" to create a matching predicate.
* It relies on {@link #createPredicate(String, PredicateType)} and combine both in a single predicate.
*
* @param propertyBase the prefix to use to read predicate properties.
* @param type the type of matching.
* @return the predicate for that properties pair.
*/
Predicate<String> createIncludesExcludes(String propertyBase, PredicateType type);
/**
* Tries to unwrap current context in another type.
* @param type type to extract.
* @param <T> type to extract.
* @return the extracted instance.
*/
<T> T unwrap(Class<T> type);
}
enum PredicateType implements BiPredicate<String, String> {
EQUALS {
@Override
public boolean test(final String value, final String item) {
return Objects.equals(value, item);
}
},
STARTS_WITH {
@Override
public boolean test(final String value, final String item) {
return item != null && item.startsWith(value);
}
},
MATCHES {
@Override
public boolean test(final String value, final String item) {
return item != null && item.matches(value);
}
}
}
}