/* * Copyright (c) MuleSoft, Inc. All rights reserved. http://www.mulesoft.com * The software in this package is published under the terms of the CPAL v1.0 * license, a copy of which has been included with this distribution in the * LICENSE.txt file. */ package org.mule.runtime.module.extension.internal.loader.java; import static java.lang.String.format; import static java.util.Arrays.asList; import static org.mule.runtime.api.meta.model.connection.ConnectionManagementType.CACHED; import static org.mule.runtime.api.meta.model.connection.ConnectionManagementType.NONE; import static org.mule.runtime.api.meta.model.connection.ConnectionManagementType.POOLING; import static org.mule.runtime.module.extension.internal.ExtensionProperties.DEFAULT_CONNECTION_PROVIDER_NAME; import org.mule.runtime.api.connection.CachedConnectionProvider; import org.mule.runtime.api.connection.ConnectionProvider; import org.mule.runtime.api.connection.PoolingConnectionProvider; import org.mule.runtime.api.meta.model.connection.ConnectionManagementType; import org.mule.runtime.api.meta.model.declaration.fluent.ConnectionProviderDeclarer; import org.mule.runtime.api.meta.model.declaration.fluent.HasConnectionProviderDeclarer; import org.mule.runtime.extension.api.annotation.connectivity.oauth.AuthorizationCode; import org.mule.runtime.extension.api.connectivity.oauth.AuthorizationCodeGrantType; import org.mule.runtime.extension.api.connectivity.oauth.OAuthModelProperty; import org.mule.runtime.extension.api.exception.IllegalConnectionProviderModelDefinitionException; import org.mule.runtime.module.extension.internal.loader.java.property.ConnectionProviderFactoryModelProperty; import org.mule.runtime.module.extension.internal.loader.java.property.ConnectionTypeModelProperty; import org.mule.runtime.module.extension.internal.loader.java.property.ImplementingTypeModelProperty; import org.mule.runtime.module.extension.internal.loader.java.type.ConnectionProviderElement; import org.mule.runtime.module.extension.internal.loader.java.type.WithConnectionProviders; import org.mule.runtime.module.extension.internal.loader.utils.ParameterDeclarationContext; import java.util.HashMap; import java.util.List; import java.util.Map; /** * Helper class for declaring connection providers through a {@link DefaultJavaModelLoaderDelegate} * @since 4.0 */ final class ConnectionProviderModelLoaderDelegate extends AbstractModelLoaderDelegate { private static final String CUSTOM_CONNECTION_PROVIDER_SUFFIX = "-" + DEFAULT_CONNECTION_PROVIDER_NAME; private static final String CONNECTION_PROVIDER = "Connection Provider"; private final Map<Class<?>, ConnectionProviderDeclarer> connectionProviderDeclarers = new HashMap<>(); ConnectionProviderModelLoaderDelegate(DefaultJavaModelLoaderDelegate loader) { super(loader); } void declareConnectionProviders(HasConnectionProviderDeclarer declarer, WithConnectionProviders withConnectionProviders) { withConnectionProviders.getConnectionProviders().forEach(provider -> declareConnectionProvider(declarer, provider)); } private void declareConnectionProvider(HasConnectionProviderDeclarer declarer, ConnectionProviderElement providerType) { final Class<?> providerClass = providerType.getDeclaringClass(); ConnectionProviderDeclarer providerDeclarer = connectionProviderDeclarers.get(providerClass); if (providerDeclarer != null) { declarer.withConnectionProvider(providerDeclarer); return; } String name = providerType.getAlias() + CUSTOM_CONNECTION_PROVIDER_SUFFIX; String description = providerType.getDescription(); if (providerType.getName().equals(providerType.getAlias())) { name = DEFAULT_CONNECTION_PROVIDER_NAME; } List<Class<?>> providerGenerics = providerType.getInterfaceGenerics(ConnectionProvider.class); if (providerGenerics.size() != 1) { // TODO: MULE-9220: Add a syntax validator for this throw new IllegalConnectionProviderModelDefinitionException( format("Connection provider class '%s' was expected to have 1 generic type " + "(for the connection type) but %d were found", providerType.getName(), providerGenerics.size())); } providerDeclarer = declarer.withConnectionProvider(name).describedAs(description) .withModelProperty(new ConnectionProviderFactoryModelProperty(new DefaultConnectionProviderFactory<>( providerClass, getExtensionType() .getClassLoader()))) .withModelProperty(new ConnectionTypeModelProperty(providerGenerics.get(0))) .withModelProperty(new ImplementingTypeModelProperty(providerClass)); loader.parseExternalLibs(providerType, providerDeclarer); ConnectionManagementType managementType = NONE; if (PoolingConnectionProvider.class.isAssignableFrom(providerClass)) { managementType = POOLING; } else if (CachedConnectionProvider.class.isAssignableFrom(providerClass)) { managementType = CACHED; } parseOAuthGrantType(providerType, providerDeclarer); providerDeclarer.withConnectionManagementType(managementType); connectionProviderDeclarers.put(providerClass, providerDeclarer); ParameterDeclarationContext context = new ParameterDeclarationContext(CONNECTION_PROVIDER, providerDeclarer.getDeclaration()); loader.getFieldParametersLoader().declare(providerDeclarer, providerType.getParameters(), context); } private void parseOAuthGrantType(ConnectionProviderElement providerType, ConnectionProviderDeclarer providerDeclarer) { providerType.getAnnotation(AuthorizationCode.class).ifPresent(a -> { AuthorizationCodeGrantType grantType = new AuthorizationCodeGrantType(a.accessTokenUrl(), a.authorizationUrl(), a.accessTokenExpr(), a.expirationExpr(), a.refreshTokenExpr(), a.defaultScopes()); providerDeclarer.withModelProperty(new OAuthModelProperty(asList(grantType))); }); } }