Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Provide Project via injection #672

Merged
merged 12 commits into from
Nov 7, 2017
37 changes: 0 additions & 37 deletions app/Module.java
Original file line number Diff line number Diff line change
@@ -1,19 +1,9 @@
import com.commercetools.sunrise.cms.CmsService;
import com.commercetools.sunrise.ctp.categories.CachedCategoryTreeProvider;
import com.commercetools.sunrise.ctp.categories.CategoriesSettings;
import com.commercetools.sunrise.ctp.categories.NavigationCategoryTree;
import com.commercetools.sunrise.ctp.categories.NewCategoryTree;
import com.commercetools.sunrise.email.EmailSender;
import com.commercetools.sunrise.framework.controllers.metrics.SimpleMetricsSphereClientProvider;
import com.commercetools.sunrise.framework.injection.RequestScoped;
import com.commercetools.sunrise.framework.localization.CountryFromSessionProvider;
import com.commercetools.sunrise.framework.localization.CurrencyFromCountryProvider;
import com.commercetools.sunrise.framework.localization.LocaleFromUrlProvider;
import com.commercetools.sunrise.framework.template.cms.FileBasedCmsServiceProvider;
import com.commercetools.sunrise.framework.template.engine.HandlebarsTemplateEngineProvider;
import com.commercetools.sunrise.framework.template.engine.TemplateEngine;
import com.commercetools.sunrise.framework.template.i18n.ConfigurableI18nResolverProvider;
import com.commercetools.sunrise.framework.template.i18n.I18nResolver;
import com.commercetools.sunrise.framework.viewmodels.content.carts.MiniCartViewModelFactory;
import com.commercetools.sunrise.httpauth.HttpAuthentication;
import com.commercetools.sunrise.httpauth.basic.BasicAuthenticationProvider;
Expand Down Expand Up @@ -61,11 +51,6 @@ public class Module extends AbstractModule {

@Override
protected void configure() {
// Binding for the client to connect commercetools
bind(SphereClient.class)
.toProvider(SimpleMetricsSphereClientProvider.class)
.in(Singleton.class);

// Binding for the HTTP Authentication
bind(HttpAuthentication.class)
.toProvider(BasicAuthenticationProvider.class)
Expand All @@ -74,33 +59,11 @@ protected void configure() {
// Binding for category tree
bind(CategoryTree.class).toProvider(CachedCategoryTreeProvider.class);

// Binding for all template related, such as the engine, CMS and i18n
bind(CmsService.class)
.toProvider(FileBasedCmsServiceProvider.class)
.in(Singleton.class);
bind(TemplateEngine.class)
.toProvider(HandlebarsTemplateEngineProvider.class)
.in(Singleton.class);
bind(I18nResolver.class)
.toProvider(ConfigurableI18nResolverProvider.class)
.in(Singleton.class);

// Bindings fo email sender
bind(EmailSender.class)
.toProvider(EmailSenderProvider.class)
.in(Singleton.class);

// Bindings for all user context related
bind(Locale.class)
.toProvider(LocaleFromUrlProvider.class)
.in(RequestScoped.class);
bind(CountryCode.class)
.toProvider(CountryFromSessionProvider.class)
.in(RequestScoped.class);
bind(CurrencyUnit.class)
.toProvider(CurrencyFromCountryProvider.class)
.in(RequestScoped.class);

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Removed from Module.java, because this file belongs to Starter Project and is therefore never updated with new releases, what makes migration more difficult. Now moved to LocalizationModule, which is enabled by default on reference.conf (default configuration), and can be disabled via configuration as explained in #671 in order to bind your own implementations.

// Bindings for the configured faceted search mappers
bind(TermFacetViewModelFactory.class)
.annotatedWith(Names.named("alphabeticallySorted"))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
import com.commercetools.sunrise.framework.viewmodels.SimpleViewModelFactory;
import com.commercetools.sunrise.framework.viewmodels.forms.countries.CountryFormSelectableOptionViewModel;
import com.commercetools.sunrise.framework.viewmodels.forms.countries.CountryFormSelectableOptionViewModelFactory;
import com.commercetools.sunrise.framework.localization.ProjectContext;
import com.commercetools.sunrise.ctp.project.ProjectContext;
import com.commercetools.sunrise.framework.injection.RequestScoped;
import com.neovisionaries.i18n.CountryCode;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,9 @@

import javax.inject.Inject;

/**
* Provides a {@link SphereClientConfig} extracted from the application's configuration.
*/
public final class SphereClientConfigProvider implements Provider<SphereClientConfig> {

private static final String CONFIG_ROOT = "sunrise.ctp.client";
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
package com.commercetools.sunrise.ctp.client;

import com.commercetools.sunrise.framework.controllers.metrics.SimpleMetricsSphereClientProvider;
import com.google.inject.AbstractModule;
import io.sphere.sdk.client.SphereClient;
import io.sphere.sdk.client.SphereClientConfig;

import javax.inject.Singleton;

/**
* Module that allows to inject a {@link SphereClient} and its configuration.
*/
public final class SphereClientModule extends AbstractModule {

@Override
protected void configure() {
bind(SphereClientConfig.class)
.toProvider(SphereClientConfigProvider.class)
.in(Singleton.class);

bind(SphereClient.class)
.toProvider(SimpleMetricsSphereClientProvider.class)
.in(Singleton.class);
}
}
Original file line number Diff line number Diff line change
@@ -1,7 +1,12 @@
package com.commercetools.sunrise.framework.localization;
package com.commercetools.sunrise.ctp.project;

import com.commercetools.sunrise.framework.localization.NoCountryFoundException;
import com.commercetools.sunrise.framework.localization.NoCurrencyFoundException;
import com.commercetools.sunrise.framework.localization.NoLocaleFoundException;
import com.google.inject.ImplementedBy;
import com.neovisionaries.i18n.CountryCode;
import io.sphere.sdk.projects.Project;
import play.Configuration;

import javax.money.CurrencyUnit;
import java.util.List;
Expand Down Expand Up @@ -64,4 +69,8 @@ default boolean isCountrySupported(final CountryCode countryCode) {
default boolean isCurrencySupported(final CurrencyUnit currency) {
return currencies().contains(currency);
}

static ProjectContext of(final Configuration globalConfig, final String configPath, final Project project) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

To me it looks like this method isn't used or do you plan to use it in tests?

return new ProjectContextImpl(globalConfig, configPath, project);
}
}
Original file line number Diff line number Diff line change
@@ -1,13 +1,9 @@
package com.commercetools.sunrise.framework.localization;
package com.commercetools.sunrise.ctp.project;

import com.commercetools.sunrise.play.configuration.SunriseConfigurationException;
import com.neovisionaries.i18n.CountryCode;
import io.sphere.sdk.client.SphereClient;
import io.sphere.sdk.client.SphereRequest;
import io.sphere.sdk.client.SphereTimeoutException;
import io.sphere.sdk.models.Base;
import io.sphere.sdk.projects.Project;
import io.sphere.sdk.projects.queries.ProjectGet;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import play.Configuration;
Expand All @@ -16,12 +12,10 @@
import javax.inject.Singleton;
import javax.money.CurrencyUnit;
import javax.money.Monetary;
import java.time.Duration;
import java.util.List;
import java.util.Locale;
import java.util.function.Function;

import static io.sphere.sdk.client.SphereClientUtils.blockingWait;
import static java.util.Collections.emptyList;
import static java.util.stream.Collectors.toList;

Expand All @@ -34,26 +28,22 @@
final class ProjectContextImpl extends Base implements ProjectContext {

private static final Logger LOGGER = LoggerFactory.getLogger(ProjectContext.class);
private static final String CONFIG_LANGUAGES = "application.i18n.languages";
private static final String CONFIG_COUNTRIES = "application.countries";
private static final String CONFIG_CURRENCIES = "application.currencies";

private final List<Locale> locales;
private final List<CountryCode> countryCodes;
private final List<CurrencyUnit> currencies;

@Inject
ProjectContextImpl(final Configuration configuration, final SphereClient client) {
try {
final SphereRequest<Project> request = ProjectGet.of();
final Project project = blockingWait(client.execute(request), Duration.ofMinutes(1));
this.locales = projectLocales(configuration, project);
this.countryCodes = projectCountries(configuration, project);
this.currencies = projectCurrencies(configuration, project);
LOGGER.debug("Project Languages {}, Countries {}, Currencies {}", locales, countryCodes, currencies);
} catch (SphereTimeoutException e) {
throw new RuntimeException("Could not fetch project information", e);
}
ProjectContextImpl(final Configuration globalConfig, final Project project) {
this(globalConfig, "sunrise.ctp.project", project);
}

ProjectContextImpl(final Configuration globalConfig, final String configPath, final Project project) {
final Configuration config = globalConfig.getConfig(configPath);
this.locales = projectLocales(config, project);
this.countryCodes = projectCountries(config, project);
this.currencies = projectCurrencies(config, project);
LOGGER.debug("Initialized ProjectContext: Languages {}, Countries {}, Currencies {}", locales, countryCodes, currencies);
}

@Override
Expand All @@ -72,15 +62,15 @@ public List<CurrencyUnit> currencies() {
}

private static List<Locale> projectLocales(final Configuration configuration, final Project project) {
return getValues(configuration, CONFIG_LANGUAGES, Locale::forLanguageTag, project.getLanguageLocales());
return getValues(configuration, "languages", Locale::forLanguageTag, project.getLanguageLocales());
}

private static List<CountryCode> projectCountries(final Configuration configuration, final Project project) {
return getValues(configuration, CONFIG_COUNTRIES, CountryCode::getByCode, project.getCountries());
return getValues(configuration, "countries", CountryCode::getByCode, project.getCountries());
}

private static List<CurrencyUnit> projectCurrencies(final Configuration configuration, final Project project) {
return getValues(configuration, CONFIG_CURRENCIES, Monetary::getCurrency, project.getCurrencyUnits());
return getValues(configuration, "currencies", Monetary::getCurrency, project.getCurrencyUnits());
}

private static <T> List<T> getValues(final Configuration configuration, final String configKey,
Expand All @@ -94,4 +84,4 @@ private static <T> List<T> getValues(final Configuration configuration, final St
}
return values;
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
package com.commercetools.sunrise.ctp.project;

import com.google.inject.AbstractModule;
import io.sphere.sdk.projects.Project;

import javax.inject.Singleton;

/**
* Module that allows to inject a commercetools {@link Project}.
*/
public final class ProjectModule extends AbstractModule {

@Override
protected void configure() {
bind(Project.class)
.toProvider(ProjectProvider.class)
.in(Singleton.class);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
package com.commercetools.sunrise.ctp.project;

import io.sphere.sdk.client.SphereClient;
import io.sphere.sdk.client.SphereRequest;
import io.sphere.sdk.projects.Project;
import io.sphere.sdk.projects.queries.ProjectGet;

import javax.inject.Inject;
import javax.inject.Provider;
import java.time.Duration;

import static io.sphere.sdk.client.SphereClientUtils.blockingWait;

/**
* Provides the commercetools {@link Project} associated with the injected {@link SphereClient}.
*/
public final class ProjectProvider implements Provider<Project> {

private final SphereClient sphereClient;

@Inject
ProjectProvider(final SphereClient sphereClient) {
this.sphereClient = sphereClient;
}

@Override
public Project get() {
final SphereRequest<Project> request = ProjectGet.of();
return blockingWait(sphereClient.execute(request), Duration.ofSeconds(30));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -11,13 +11,16 @@

import static java.util.concurrent.CompletableFuture.completedFuture;

/**
* Provides a {@link SphereClient} using the {@link SimpleMetricsSphereClient} implementation.
*/
public final class SimpleMetricsSphereClientProvider implements Provider<SimpleMetricsSphereClient> {

private final ApplicationLifecycle applicationLifecycle;
private final SphereClientConfig sphereClientConfig;

@Inject
public SimpleMetricsSphereClientProvider(final ApplicationLifecycle applicationLifecycle, final SphereClientConfig sphereClientConfig) {
SimpleMetricsSphereClientProvider(final ApplicationLifecycle applicationLifecycle, final SphereClientConfig sphereClientConfig) {
this.applicationLifecycle = applicationLifecycle;
this.sphereClientConfig = sphereClientConfig;
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,21 +1,17 @@
package com.commercetools.sunrise.framework.injection;

import com.commercetools.sunrise.ctp.client.SphereClientConfigProvider;
import com.google.inject.AbstractModule;
import io.sphere.sdk.client.SphereClientConfig;
import io.sphere.sdk.utils.MoneyImpl;

import javax.inject.Singleton;
import javax.money.Monetary;
import javax.money.format.MonetaryFormats;

public class SunriseModule extends AbstractModule {
public final class SunriseModule extends AbstractModule {

@Override
protected void configure() {
applyJavaMoneyHack();
bindScope(RequestScoped.class, new RequestScope());
bind(SphereClientConfig.class).toProvider(SphereClientConfigProvider.class).in(Singleton.class);
}

private void applyJavaMoneyHack() {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,19 +1,24 @@
package com.commercetools.sunrise.framework.localization;

import com.commercetools.sunrise.ctp.project.ProjectContext;
import com.commercetools.sunrise.sessions.country.CountryInSession;
import com.neovisionaries.i18n.CountryCode;

import javax.inject.Inject;
import javax.inject.Provider;
import java.util.Optional;

/**
* Provides the {@link CountryCode} instance of the country saved in the user's session.
* If not set, it provides the default country from the project.
*/
public final class CountryFromSessionProvider implements Provider<CountryCode> {

private final ProjectContext projectContext;
private final CountryInSession countryInSession;

@Inject
public CountryFromSessionProvider(final ProjectContext projectContext, final CountryInSession countryInSession) {
CountryFromSessionProvider(final ProjectContext projectContext, final CountryInSession countryInSession) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice that you removed the public modifier here. And we now could remove the public modifier from this class too.

this.projectContext = projectContext;
this.countryInSession = countryInSession;
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package com.commercetools.sunrise.framework.localization;

import com.commercetools.sunrise.ctp.project.ProjectContext;
import com.neovisionaries.i18n.CountryCode;

import javax.inject.Inject;
Expand All @@ -8,13 +9,16 @@
import javax.money.Monetary;
import java.util.Optional;

/**
* Provides the {@link CurrencyUnit} corresponding to the injected {@link CountryCode}.
*/
public final class CurrencyFromCountryProvider implements Provider<CurrencyUnit> {

private final CountryCode country;
private final ProjectContext projectContext;

@Inject
public CurrencyFromCountryProvider(final CountryCode country, final ProjectContext projectContext) {
CurrencyFromCountryProvider(final CountryCode country, final ProjectContext projectContext) {
this.country = country;
this.projectContext = projectContext;
}
Expand Down
Loading