001/** 002 * Copyright (C) 2006-2022 Talend Inc. - www.talend.com 003 * 004 * Licensed under the Apache License, Version 2.0 (the "License"); 005 * you may not use this file except in compliance with the License. 006 * You may obtain a copy of the License at 007 * 008 * http://www.apache.org/licenses/LICENSE-2.0 009 * 010 * Unless required by applicable law or agreed to in writing, software 011 * distributed under the License is distributed on an "AS IS" BASIS, 012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 013 * See the License for the specific language governing permissions and 014 * limitations under the License. 015 */ 016package org.talend.sdk.component.spi.component; 017 018import static java.util.Collections.emptyList; 019import static java.util.Collections.emptyMap; 020 021import java.lang.instrument.ClassFileTransformer; 022import java.util.Collection; 023import java.util.Collections; 024import java.util.Map; 025 026/** 027 * Provide a way to interact with component scanning and metadata extraction. 028 * 029 * Note: it requires to use 030 * org.talend.sdk.component.runtime.manager.ComponentManager to be activated. 031 */ 032public interface ComponentExtension { 033 034 /** 035 * @return true if the extension can be used in current environment. 036 */ 037 default boolean isActive() { 038 return true; 039 } 040 041 /** 042 * @param context 043 * the component context allowing to interact with the container. 044 */ 045 void onComponent(ComponentContext context); 046 047 /** 048 * @param componentType 049 * the expected framework component type (can be Mapper or 050 * Processor). 051 * @return true if convert can be used for that kind of component, false 052 * otherwise. 053 */ 054 boolean supports(Class<?> componentType); 055 056 /** 057 * Note: you can assume supports() was called before going into this method. 058 * 059 * @param instance 060 * the instantiated component (native instance). 061 * @param component 062 * the expected framework component type (can be Mapper or 063 * Processor). 064 * @param <T> 065 * the generic matching component parameter. 066 * @return an instance of component. 067 */ 068 <T> T convert(ComponentInstance instance, Class<T> component); 069 070 /** 071 * @param plugin the plugin to enrich with services. 072 * @return the services specific to the extension. 073 */ 074 default Map<Class<?>, Object> getExtensionServices(final String plugin) { 075 return emptyMap(); 076 } 077 078 /** 079 * The priority of the extension. 080 * Extensions are sorted by priority and the first one matching (supports) wins. 081 * 082 * @return the priority for this extension, smaller is the highest priority. 083 */ 084 default int priority() { 085 return Integer.MAX_VALUE; 086 } 087 088 /** 089 * Unwrap the current instance to another type. Useful to access advanced features of some extensions. 090 * 091 * @param type the expected type. 092 * @param args optional parameters for the unwrapping. 093 * @param <T> the type to cast the extension to. 094 * @return the unwrapped instance or null if not supported. 095 */ 096 default <T> T unwrap(final Class<T> type, final Object... args) { 097 if (type.isInstance(this)) { 098 return type.cast(this); 099 } 100 return null; 101 } 102 103 /** 104 * @return a list of transformer to set on the component classloader. 105 */ 106 default Collection<ClassFileTransformer> getTransformers() { 107 return emptyList(); 108 } 109 110 /** 111 * @return a Stream of dependencies coordinates 112 */ 113 default Collection<String> getAdditionalDependencies() { 114 return Collections.emptyList(); 115 } 116 117 /** 118 * This is the handle giving the extension information about the component being 119 * processed and allowing to interact with the container lifecycle. 120 */ 121 interface ComponentInstance { 122 123 /** 124 * @return the component native instance. 125 */ 126 Object instance(); 127 128 /** 129 * @return the plugin identifier of the component. 130 */ 131 String plugin(); 132 133 /** 134 * @return the family identifier of the component. 135 */ 136 String family(); 137 138 /** 139 * @return the name identifier of the component. 140 */ 141 String name(); 142 } 143 144 /** 145 * This is the handle giving the extension information about the component being 146 * processed and allowing to interact with the container lifecycle. 147 */ 148 interface ComponentContext { 149 150 /** 151 * @return the class representing the component. 152 */ 153 Class<?> getType(); 154 155 /** 156 * will prevent the component to be usable with findMapper()/findProcessor() but 157 * will also deactivate the associated validation so you can 158 * use @PartitionMapper and @Processor for another runtime than the framework 159 * default one. 160 */ 161 void skipValidation(); 162 163 /** 164 * Useful for extensions needing to access metadata from another programming model. 165 * Exposing the extension allows to unwrap it to access it. 166 * 167 * @return null if no extension owns the component, the extension instance otherwise. 168 */ 169 ComponentExtension owningExtension(); 170 } 171}