Skip to content

Commit

Permalink
Bugfix
Browse files Browse the repository at this point in the history
  • Loading branch information
mercyblitz committed Apr 22, 2024
1 parent 6f3dc3d commit 17e93d9
Show file tree
Hide file tree
Showing 10 changed files with 125 additions and 320 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,9 @@

import io.microsphere.i18n.spring.boot.actuate.I18nEndpoint;
import io.microsphere.i18n.spring.boot.autoconfigure.I18nAutoConfiguration;
import io.microsphere.i18n.spring.boot.condition.ConditionalOnI18nEnabled;
import org.springframework.boot.actuate.autoconfigure.endpoint.condition.ConditionalOnAvailableEndpoint;
import org.springframework.boot.autoconfigure.AutoConfigureAfter;
import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.context.annotation.Bean;
Expand All @@ -33,10 +33,9 @@
* @since 1.0.0
*/
@ConditionalOnClass(name = {
"io.microsphere.i18n.ServiceMessageSource", // microsphere-i18n-core
"io.microsphere.i18n.spring.context.I18nConfiguration", // microsphere-i18n-spring
"org.springframework.boot.actuate.endpoint.annotation.Endpoint", // spring-boot-actuator-autoconfigure
})
@ConditionalOnI18nEnabled
@ConditionalOnAvailableEndpoint(endpoint = I18nEndpoint.class)
@AutoConfigureAfter(I18nAutoConfiguration.class)
public class I18nEndpointAutoConfiguration {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,21 +16,20 @@
*/
package io.microsphere.i18n.spring.boot.autoconfigure;

import io.microsphere.i18n.spring.context.I18nConfiguration;
import io.microsphere.i18n.spring.annotation.EnableI18n;
import io.microsphere.i18n.spring.boot.condition.ConditionalOnI18nEnabled;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.context.annotation.Import;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;

import static io.microsphere.i18n.spring.constants.I18nConstants.ENABLED_PROPERTY_NAME;

/**
* I18n Auto-Configuration
*
* @author <a href="mailto:[email protected]">Mercy</a>
* @see I18nConfiguration
* @since 1.0.0
*/
@ConditionalOnClass(name = {
"io.microsphere.i18n.ServiceMessageSource", // microsphere-i18n-core
"io.microsphere.i18n.spring.context.I18nConfiguration", // microsphere-i18n-spring
})
@Import(I18nConfiguration.class)
@ConditionalOnI18nEnabled
@EnableI18n
public class I18nAutoConfiguration {
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
package io.microsphere.i18n.spring.boot.condition;

import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.context.annotation.Conditional;

import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

import static io.microsphere.i18n.spring.constants.I18nConstants.ENABLED_PROPERTY_NAME;

/**
* {@link Conditional @Conditional} that checks whether the I18n enabled
*
* @author <a href="mailto:[email protected]">Mercy</a>
* @since 1.0.0
*/
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.TYPE, ElementType.METHOD})
@Documented
@ConditionalOnClass(name = {
"io.microsphere.i18n.ServiceMessageSource", // microsphere-i18n-core
"io.microsphere.i18n.spring.annotation.EnableI18n", // microsphere-i18n-spring
})
@ConditionalOnProperty(name = ENABLED_PROPERTY_NAME, matchIfMissing = true)
public @interface ConditionalOnI18nEnabled {

}
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,10 @@
import static io.microsphere.i18n.ServiceMessageSource.COMMON_SOURCE;

/**
* Enables the extension for Spring Internationalisation
* Enables the extension for Spring Internationalisation.
* <p>
* The feature could be disabled by the Spring property if
* {@link I18nConstants#ENABLED_PROPERTY_NAME "microsphere.i18n.enabled"} is <code>false</code>
*
* @author <a href="mailto:[email protected]">Mercy<a/>
* @see I18nImportBeanDefinitionRegistrar
Expand All @@ -48,13 +51,20 @@
public @interface EnableI18n {

/**
* Declares the sources of the {@link ServiceMessageSource} as the {@link ServiceMessageSourceFactoryBean} Spring Beans
* to be registered.
* Declares the sources of the {@link ServiceMessageSource} to register the {@link ServiceMessageSourceFactoryBean}
* Spring Beans whose names are composed by their source content appending "ServiceMessageSource", the default value
* is {@value ServiceMessageSource#COMMON_SOURCE "common"} indicates that the named "commonServiceMessageSource"
* Spring Bean will be registered.
* <p>
* The attribute value will be merged from the Spring property whose name is {@link I18nConstants#SOURCES_PROPERTY_NAME}
* Besides the attribute value, the sources will be extended from the Spring property whose name is
* {@link I18nConstants#SOURCES_PROPERTY_NAME "microsphere.i18n.sources"}.
* <p>
* Finally, all sourced {@link ServiceMessageSource} Spring Beans as the members will be composited into
* a Primary Spring Bean named {@link I18nConstants#SERVICE_MESSAGE_SOURCE_BEAN_NAME "serviceMessageSource"}.
*
* @return {@link ServiceMessageSource#COMMON_SOURCE} as the default
* @return {@link ServiceMessageSource#COMMON_SOURCE "common"} as the default
* @see I18nConstants#SOURCES_PROPERTY_NAME
* @see I18nConstants#SERVICE_MESSAGE_SOURCE_BEAN_NAME
*/
String[] sources() default {COMMON_SOURCE};

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@
import io.microsphere.i18n.spring.beans.factory.support.ServiceMessageSourceBeanLifecyclePostProcessor;
import io.microsphere.i18n.spring.context.I18nApplicationListener;
import io.microsphere.i18n.spring.context.MessageSourceAdapter;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
import org.springframework.context.EnvironmentAware;
Expand All @@ -35,6 +37,8 @@
import java.util.Set;
import java.util.function.Supplier;

import static io.microsphere.i18n.spring.constants.I18nConstants.DEFAULT_ENABLED;
import static io.microsphere.i18n.spring.constants.I18nConstants.ENABLED_PROPERTY_NAME;
import static io.microsphere.i18n.spring.constants.I18nConstants.SERVICE_MESSAGE_SOURCE_BEAN_NAME;
import static io.microsphere.i18n.spring.constants.I18nConstants.SOURCES_PROPERTY_NAME;
import static io.microsphere.spring.util.BeanRegistrar.registerBeanDefinition;
Expand All @@ -55,15 +59,19 @@ public class I18nImportBeanDefinitionRegistrar implements ImportBeanDefinitionRe

private static final Class<? extends Annotation> ANNOTATION_TYPE = EnableI18n.class;

private static Logger logger = LoggerFactory.getLogger(ANNOTATION_TYPE);

private Environment environment;

@Override
public void registerBeanDefinitions(AnnotationMetadata metadata, BeanDefinitionRegistry registry) {
AnnotationAttributes attributes = fromMap(metadata.getAnnotationAttributes(ANNOTATION_TYPE.getName()));
registerServiceMessageSourceBeanDefinitions(attributes, registry);
registerMessageSourceAdapterBeanDefinition(attributes, registry);
registerI18nApplicationListenerBeanDefinition(registry);
registerBeanPostProcessorBeanDefinitions(registry);
if (isEnabled()) {
AnnotationAttributes attributes = fromMap(metadata.getAnnotationAttributes(ANNOTATION_TYPE.getName()));
registerServiceMessageSourceBeanDefinitions(attributes, registry);
registerMessageSourceAdapterBeanDefinition(attributes, registry);
registerI18nApplicationListenerBeanDefinition(registry);
registerBeanPostProcessorBeanDefinitions(registry);
}
}

private void registerServiceMessageSourceBeanDefinitions(AnnotationAttributes attributes, BeanDefinitionRegistry registry) {
Expand Down Expand Up @@ -112,4 +120,14 @@ private void registerBeanPostProcessorBeanDefinitions(BeanDefinitionRegistry reg
public void setEnvironment(Environment environment) {
this.environment = environment;
}

private boolean isEnabled() {
String propertyName = ENABLED_PROPERTY_NAME;
boolean enabled = environment.getProperty(propertyName, boolean.class, DEFAULT_ENABLED);
logger.debug("Microsphere i18n is {} , cased by the Spring property[name : '{}', default value : '{}']",
enabled ? "enabled" : "disabled",
propertyName,
DEFAULT_ENABLED);
return enabled;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -17,16 +17,25 @@
package io.microsphere.i18n.spring.context;

import io.microsphere.i18n.ServiceMessageSource;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationEvent;
import org.springframework.context.ApplicationListener;
import org.springframework.context.event.ContextClosedEvent;
import org.springframework.context.event.ContextRefreshedEvent;
import org.springframework.context.event.SmartApplicationListener;
import org.springframework.web.servlet.i18n.AcceptHeaderLocaleResolver;

import java.util.List;
import java.util.Locale;

import static io.microsphere.i18n.spring.constants.I18nConstants.SERVICE_MESSAGE_SOURCE_BEAN_NAME;
import static io.microsphere.i18n.util.I18nUtils.destroyServiceMessageSource;
import static io.microsphere.i18n.util.I18nUtils.setServiceMessageSource;
import static io.microsphere.spring.util.BeanUtils.getOptionalBean;
import static io.microsphere.spring.util.BeanUtils.getSortedBeans;
import static io.microsphere.util.ClassLoaderUtils.resolveClass;
import static org.springframework.util.ObjectUtils.containsElement;

/**
Expand All @@ -38,6 +47,12 @@
*/
public class I18nApplicationListener implements SmartApplicationListener {

private static final Logger logger = LoggerFactory.getLogger(I18nApplicationListener.class);

private static final String ACCEPT_HEADER_LOCALE_RESOLVER_CLASS_NAME = "org.springframework.web.servlet.i18n.AcceptHeaderLocaleResolver";

private static final Class<?> ACCEPT_HEADER_LOCALE_RESOLVER_CLASS = resolveClass(ACCEPT_HEADER_LOCALE_RESOLVER_CLASS_NAME);

private static final Class<?>[] SUPPORTED_EVENT_TYPES = {
ContextRefreshedEvent.class,
ContextClosedEvent.class
Expand All @@ -60,11 +75,43 @@ public void onApplicationEvent(ApplicationEvent event) {
private void onContextRefreshedEvent(ContextRefreshedEvent event) {
ApplicationContext context = event.getApplicationContext();

initializeServiceMessageSource(context);

initializeAcceptHeaderLocaleResolver(context);
}

private void initializeServiceMessageSource(ApplicationContext context) {
ServiceMessageSource serviceMessageSource = context.getBean(SERVICE_MESSAGE_SOURCE_BEAN_NAME, ServiceMessageSource.class);
setServiceMessageSource(serviceMessageSource);
}


private void initializeAcceptHeaderLocaleResolver(ApplicationContext context) {
if (ACCEPT_HEADER_LOCALE_RESOLVER_CLASS == null) {
logger.debug("The class '{}' was not found!", ACCEPT_HEADER_LOCALE_RESOLVER_CLASS_NAME);
return;
}

Class<AcceptHeaderLocaleResolver> beanClass = (Class<AcceptHeaderLocaleResolver>) ACCEPT_HEADER_LOCALE_RESOLVER_CLASS;

List<AcceptHeaderLocaleResolver> acceptHeaderLocaleResolvers = getSortedBeans(context, beanClass);

if (acceptHeaderLocaleResolvers.isEmpty()) {
logger.debug("The '{}' Spring Bean was not found!", ACCEPT_HEADER_LOCALE_RESOLVER_CLASS_NAME);
return;
}

ServiceMessageSource serviceMessageSource = getOptionalBean(context, ServiceMessageSource.class);

for (AcceptHeaderLocaleResolver acceptHeaderLocaleResolver : acceptHeaderLocaleResolvers) {
Locale defaultLocale = serviceMessageSource.getDefaultLocale();
List<Locale> supportedLocales = serviceMessageSource.getSupportedLocales();
acceptHeaderLocaleResolver.setDefaultLocale(defaultLocale);
acceptHeaderLocaleResolver.setSupportedLocales(supportedLocales);
logger.debug("AcceptHeaderLocaleResolver Bean associated with default Locale : '{}' , list of supported Locales : {}", defaultLocale, supportedLocales);
}
}

private void onContextClosedEvent(ContextClosedEvent event) {
destroyServiceMessageSource();
}
Expand Down

This file was deleted.

Loading

0 comments on commit 17e93d9

Please sign in to comment.