All Downloads are FREE. Search and download functionalities are using the official Maven repository.

fr.sii.ogham.email.sendgrid.builder.AbstractSendGridBuilder Maven / Gradle / Ivy

The newest version!
package fr.sii.ogham.email.sendgrid.builder;

import java.io.InputStream;
import java.net.MalformedURLException;
import java.net.URL;
import java.nio.file.Files;

import javax.activation.MimetypesFileTypeMap;

import org.apache.http.client.HttpClient;
import org.apache.http.impl.client.CloseableHttpClient;

import com.sendgrid.SendGrid;

import fr.sii.ogham.core.builder.Builder;
import fr.sii.ogham.core.builder.configuration.ConfigurationValueBuilder;
import fr.sii.ogham.core.builder.configuration.ConfigurationValueBuilderHelper;
import fr.sii.ogham.core.builder.configurer.Configurer;
import fr.sii.ogham.core.builder.context.BuildContext;
import fr.sii.ogham.core.builder.mimetype.MimetypeDetectionBuilder;
import fr.sii.ogham.core.builder.mimetype.MimetypeDetectionBuilderDelegate;
import fr.sii.ogham.core.builder.mimetype.SimpleMimetypeDetectionBuilder;
import fr.sii.ogham.core.fluent.AbstractParent;
import fr.sii.ogham.email.sendgrid.sender.SendGridSender;

@SuppressWarnings("squid:S00119")
public abstract class AbstractSendGridBuilder, EmailBuilder> extends AbstractParent implements Builder {
	protected final MYSELF myself;
	protected final BuildContext buildContext;
	protected MimetypeDetectionBuilder mimetypeBuilder;
	protected final ConfigurationValueBuilderHelper apiKeyValueBuilder;
	protected final ConfigurationValueBuilderHelper urlValueBuilder;
	protected CloseableHttpClient httpClient;

	@SuppressWarnings("unchecked")
	protected AbstractSendGridBuilder(Class selfType, EmailBuilder parent, BuildContext buildContext, MimetypeDetectionBuilder mimetypeBuilder) {
		super(parent);
		myself = (MYSELF) selfType.cast(this);
		this.buildContext = buildContext;
		apiKeyValueBuilder = buildContext.newConfigurationValueBuilder(myself, String.class);
		urlValueBuilder = buildContext.newConfigurationValueBuilder(myself, URL.class);
		if (mimetypeBuilder != null) {
			mimetype(mimetypeBuilder);
		}
	}

	public AbstractSendGridBuilder(Class selfType, EmailBuilder parent, BuildContext buildContext) {
		this(selfType, parent, buildContext, null);
		mimetype();
	}

	/**
	 * Set SendGrid API
	 * key.
	 * 
	 * 

* The value set using this method takes precedence over any property and * default value configured using {@link #apiKey()}. * *

	 * .apiKey("my-key")
	 * .apiKey()
	 *   .properties("${custom.property.high-priority}", "${custom.property.low-priority}")
	 *   .defaultValue("default-key")
	 * 
* *
	 * .apiKey("my-key")
	 * .apiKey()
	 *   .properties("${custom.property.high-priority}", "${custom.property.low-priority}")
	 *   .defaultValue("default-key")
	 * 
* * In both cases, {@code apiKey("my-key")} is used. * *

* If this method is called several times, only the last value is used. * *

* If {@code null} value is set, it is like not setting a value at all. The * property/default value configuration is applied. * * @param apiKey * the API key to use * @return this instance for fluent chaining */ public MYSELF apiKey(String apiKey) { apiKeyValueBuilder.setValue(apiKey); return myself; } /** * Set SendGrid API * key. * *

* This method is mainly used by {@link Configurer}s to register some * property keys and/or a default value. The aim is to let developer be able * to externalize its configuration (using system properties, configuration * file or anything else). If the developer doesn't configure any value for * the registered properties, the default value is used (if set). * *

	 * .apiKey()
	 *   .properties("${custom.property.high-priority}", "${custom.property.low-priority}")
	 *   .defaultValue("default-key")
	 * 
* *

* Non-null value set using {@link #apiKey(String)} takes precedence over * property values and default value. * *

	 * .apiKey("my-key")
	 * .apiKey()
	 *   .properties("${custom.property.high-priority}", "${custom.property.low-priority}")
	 *   .defaultValue("default-key")
	 * 
* * The value {@code "my-key"} is used regardless of the value of the * properties and default value. * *

* See {@link ConfigurationValueBuilder} for more information. * * * @return the builder to configure property keys/default value */ public ConfigurationValueBuilder apiKey() { return apiKeyValueBuilder; } /** * Set username for SendGrid HTTP API. * *

* WARNING: SendGrid v4 doesn't use username/password * anymore. You must use an {@link #apiKey(String)}. * *

* The value set using this method takes precedence over any property and * default value configured using {@link #username()}. * *

	 * .username("my-username")
	 * .username()
	 *   .properties("${custom.property.high-priority}", "${custom.property.low-priority}")
	 *   .defaultValue("default-username")
	 * 
* *
	 * .username("my-username")
	 * .username()
	 *   .properties("${custom.property.high-priority}", "${custom.property.low-priority}")
	 *   .defaultValue("default-username")
	 * 
* * In both cases, {@code username("my-username")} is used. * *

* If this method is called several times, only the last value is used. * *

* If {@code null} value is set, it is like not setting a value at all. The * property/default value configuration is applied. * * @param username * the user name for SendGrid HTTP API * @return this instance for fluent chaining * */ public abstract MYSELF username(String username); /** * Set username for SendGrid HTTP API. * *

* WARNING: SendGrid v4 doesn't use username/password * anymore. You must use an {@link #apiKey(String)}. * *

* This method is mainly used by {@link Configurer}s to register some * property keys and/or a default value. The aim is to let developer be able * to externalize its configuration (using system properties, configuration * file or anything else). If the developer doesn't configure any value for * the registered properties, the default value is used (if set). * *

	 * .username()
	 *   .properties("${custom.property.high-priority}", "${custom.property.low-priority}")
	 *   .defaultValue("default-username")
	 * 
* *

* Non-null value set using {@link #username(String)} takes precedence over * property values and default value. * *

	 * .username("my-username")
	 * .username()
	 *   .properties("${custom.property.high-priority}", "${custom.property.low-priority}")
	 *   .defaultValue("default-username")
	 * 
* * The value {@code "my-username"} is used regardless of the value of the * properties and default value. * *

* See {@link ConfigurationValueBuilder} for more information. * * @return the builder to configure property keys/default value */ public abstract ConfigurationValueBuilder username(); /** * Set password for SendGrid HTTP API. * *

* WARNING: SendGrid v4 doesn't use username/password * anymore. You must use an {@link #apiKey(String)}. * *

* The value set using this method takes precedence over any property and * default value configured using {@link #password()}. * *

	 * .password("my-password")
	 * .password()
	 *   .properties("${custom.property.high-priority}", "${custom.property.low-priority}")
	 *   .defaultValue("default-password")
	 * 
* *
	 * .password("my-password")
	 * .password()
	 *   .properties("${custom.property.high-priority}", "${custom.property.low-priority}")
	 *   .defaultValue("default-password")
	 * 
* * In both cases, {@code password("my-password")} is used. * *

* If this method is called several times, only the last value is used. * *

* If {@code null} value is set, it is like not setting a value at all. The * property/default value configuration is applied. * * @param password * the password value * @return this instance for fluent chaining */ public abstract MYSELF password(String password); /** * Set password for SendGrid HTTP API. * *

* WARNING: SendGrid v4 doesn't use username/password * anymore. You must use an {@link #apiKey(String)}. * *

* This method is mainly used by {@link Configurer}s to register some * property keys and/or a default value. The aim is to let developer be able * to externalize its configuration (using system properties, configuration * file or anything else). If the developer doesn't configure any value for * the registered properties, the default value is used (if set). * *

	 * .password()
	 *   .properties("${custom.property.high-priority}", "${custom.property.low-priority}")
	 *   .defaultValue("default-password")
	 * 
* *

* Non-null value set using {@link #password(String)} takes precedence over * property values and default value. * *

	 * .password("my-password")
	 * .password()
	 *   .properties("${custom.property.high-priority}", "${custom.property.low-priority}")
	 *   .defaultValue("default-password")
	 * 
* * The value {@code "my-password"} is used regardless of the value of the * properties and default value. * *

* See {@link ConfigurationValueBuilder} for more information. * * @return the builder to configure property keys/default value */ public abstract ConfigurationValueBuilder password(); /** * Set SendGrid API base URL. * *

* The value set using this method takes precedence over any property and * default value configured using {@link #url()}. * *

	 * .url("http://localhost/sendgrid")
	 * .url()
	 *   .properties("${custom.property.high-priority}", "${custom.property.low-priority}")
	 *   .defaultValue("http://api.sendgrid.com")
	 * 
* *
	 * .url("http://localhost/sendgrid")
	 * .url()
	 *   .properties("${custom.property.high-priority}", "${custom.property.low-priority}")
	 *   .defaultValue("http://api.sendgrid.com")
	 * 
* * In both cases, {@code url("http://localhost/sendgrid")} is used. * *

* If this method is called several times, only the last value is used. * *

* If {@code null} value is set, it is like not setting a value at all. The * property/default value configuration is applied. * * @param url * the base URL for SendGrid HTTP API * @return this instance for fluent chaining */ public MYSELF url(URL url) { urlValueBuilder.setValue(url); return myself; } /** * Set SendGrid API base URL. * *

* The value set using this method takes precedence over any property and * default value configured using {@link #url()}. * *

	 * .url("http://localhost/sendgrid")
	 * .url()
	 *   .properties("${custom.property.high-priority}", "${custom.property.low-priority}")
	 *   .defaultValue("http://api.sendgrid.com")
	 * 
* *
	 * .url("http://localhost/sendgrid")
	 * .url()
	 *   .properties("${custom.property.high-priority}", "${custom.property.low-priority}")
	 *   .defaultValue("http://api.sendgrid.com")
	 * 
* * In both cases, {@code url("http://localhost/sendgrid")} is used. * *

* If this method is called several times, only the last value is used. * *

* If {@code null} value is set, it is like not setting a value at all. The * property/default value configuration is applied. * * @param url * the base URL for SendGrid HTTP API * @return this instance for fluent chaining * @throws IllegalArgumentException * if URL is malformed */ public MYSELF url(String url) { try { return url(new URL(url)); } catch (MalformedURLException e) { throw new IllegalArgumentException("Invalid URL " + url, e); } } /** * Set SendGrid API base URL. * *

* This method is mainly used by {@link Configurer}s to register some * property keys and/or a default value. The aim is to let developer be able * to externalize its configuration (using system properties, configuration * file or anything else). If the developer doesn't configure any value for * the registered properties, the default value is used (if set). * *

	 * .url()
	 *   .properties("${custom.property.high-priority}", "${custom.property.low-priority}")
	 *   .defaultValue("http://api.sendgrid.com")
	 * 
* *

* Non-null value set using {@link #url(URL)} takes precedence over property * values and default value. * *

	 * .url("http://localhost/sendgrid")
	 * .url()
	 *   .properties("${custom.property.high-priority}", "${custom.property.low-priority}")
	 *   .defaultValue("http://api.sendgrid.com")
	 * 
* * The value {@code "http://localhost/sendgrid"} is used regardless of the * value of the properties and default value. * *

* See {@link ConfigurationValueBuilder} for more information. * * * @return the builder to configure property keys/default value */ public ConfigurationValueBuilder url() { return urlValueBuilder; } /** * By default, calling SendGrid HTTP API is done through the default * {@link SendGrid} implementation that uses default {@link HttpClient} * (calling {@code HttpClientBuilder.create().build()}). If you want to use * another HTTP client implementation, you can extend the * {@link CloseableHttpClient} class and provide it: * *

	 * .client(new MyCustomHttpClient())
	 * 
* * @param httpClient * the custom implementation of {@link HttpClient} used to call * SendGrid HTTP API. SendGrid requires a * {@link CloseableHttpClient}. * @return this instance for fluent chaining */ public MYSELF httpClient(CloseableHttpClient httpClient) { this.httpClient = httpClient; return myself; } /** * Builder that configures mimetype detection. * * There exists several implementations to provide the mimetype: *
    *
  • Using Java {@link MimetypesFileTypeMap}
  • *
  • Using Java 7 {@link Files#probeContentType(java.nio.file.Path)}
  • *
  • Using Apache Tika
  • *
  • Using * JMimeMagic
  • *
* *

* Both implementations provided by Java are based on file extensions. This * can't be used in most cases as we often handle {@link InputStream}s. *

* *

* In previous version of Ogham, JMimeMagic was used and was working quite * well. Unfortunately, the library is no more maintained. *

* *

* You can configure how Tika will detect mimetype: * *

	 * .mimetype()
	 *    .tika()
	 *       ...
	 * 
* *

* This builder allows to use several providers. It will chain them until * one can find a valid mimetype. If none is found, you can explicitly * provide the default one: * *

	 * .mimetype()
	 *    .defaultMimetype("text/html")
	 * 
* *

* If no mimetype detector was previously defined, it creates a new one. * Then each time you call {@link #mimetype()}, the same instance is used. *

* * @return the builder to configure mimetype detection */ public MimetypeDetectionBuilder mimetype() { if (mimetypeBuilder == null) { mimetypeBuilder = new SimpleMimetypeDetectionBuilder<>(myself, buildContext); } return mimetypeBuilder; } /** * NOTE: this is mostly for advance usage (when creating a custom module). * * Inherits mimetype configuration from another builder. This is useful for * configuring independently different parts of Ogham but keeping a whole * coherence. * * The same instance is shared meaning that all changes done here will also * impact the other builder. * *

* If a previous builder was defined (by calling {@link #mimetype()} for * example), the new builder will override it. * * @param builder * the builder to inherit * @return this instance for fluent chaining */ public MYSELF mimetype(MimetypeDetectionBuilder builder) { mimetypeBuilder = new MimetypeDetectionBuilderDelegate<>(myself, builder); return myself; } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy