From 91130f218abe621f778ac2fe66962308ea361177 Mon Sep 17 00:00:00 2001 From: Mercy Ma Date: Fri, 17 May 2024 23:08:03 +0800 Subject: [PATCH] Add WritableOperation --- ...ropertiesResourceServiceMessageSource.java | 8 ++- .../spring/boot/actuate/I18nEndpoint.java | 71 ++++++++++++++++++- .../PropertySourcesServiceMessageSource.java | 20 +++++- 3 files changed, 95 insertions(+), 4 deletions(-) diff --git a/microsphere-i18n-core/src/main/java/io/microsphere/i18n/PropertiesResourceServiceMessageSource.java b/microsphere-i18n-core/src/main/java/io/microsphere/i18n/PropertiesResourceServiceMessageSource.java index ffb3d10..8c18940 100644 --- a/microsphere-i18n-core/src/main/java/io/microsphere/i18n/PropertiesResourceServiceMessageSource.java +++ b/microsphere-i18n-core/src/main/java/io/microsphere/i18n/PropertiesResourceServiceMessageSource.java @@ -6,6 +6,7 @@ import java.io.Reader; import java.util.HashMap; import java.util.List; +import java.util.Locale; import java.util.Map; import java.util.Properties; @@ -42,7 +43,12 @@ protected final Map loadMessages(String resource) { return messages == null ? emptyMap() : unmodifiableMap(messages); } - private Properties loadAllProperties(String resource) throws IOException { + public Properties loadAllProperties(Locale locale) throws IOException { + String resource = getResource(locale); + return loadAllProperties(resource); + } + + public Properties loadAllProperties(String resource) throws IOException { List propertiesResources = loadAllPropertiesResources(resource); logger.debug("Source '{}' loads {} Properties Resources['{}']", source, propertiesResources.size(), resource); if (isEmpty(propertiesResources)) { diff --git a/microsphere-i18n-spring-boot/src/main/java/io/microsphere/i18n/spring/boot/actuate/I18nEndpoint.java b/microsphere-i18n-spring-boot/src/main/java/io/microsphere/i18n/spring/boot/actuate/I18nEndpoint.java index af657a1..d66c535 100644 --- a/microsphere-i18n-spring-boot/src/main/java/io/microsphere/i18n/spring/boot/actuate/I18nEndpoint.java +++ b/microsphere-i18n-spring-boot/src/main/java/io/microsphere/i18n/spring/boot/actuate/I18nEndpoint.java @@ -19,13 +19,22 @@ import io.microsphere.i18n.AbstractResourceServiceMessageSource; import io.microsphere.i18n.ServiceMessageSource; import io.microsphere.i18n.spring.DelegatingServiceMessageSource; +import io.microsphere.i18n.spring.PropertySourcesServiceMessageSource; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.boot.actuate.endpoint.annotation.Endpoint; import org.springframework.boot.actuate.endpoint.annotation.ReadOperation; import org.springframework.boot.actuate.endpoint.annotation.Selector; +import org.springframework.boot.actuate.endpoint.annotation.WriteOperation; import org.springframework.cglib.core.Local; - +import org.springframework.core.env.ConfigurableEnvironment; +import org.springframework.core.env.Environment; +import org.springframework.core.env.MapPropertySource; +import org.springframework.core.env.MutablePropertySources; +import org.springframework.core.env.PropertySources; + +import java.io.IOException; +import java.io.StringWriter; import java.util.ArrayList; import java.util.HashMap; import java.util.LinkedHashMap; @@ -34,6 +43,8 @@ import java.util.List; import java.util.Locale; import java.util.Map; +import java.util.Objects; +import java.util.Properties; import java.util.Set; import static io.microsphere.i18n.spring.constants.I18nConstants.SERVICE_MESSAGE_SOURCE_BEAN_NAME; @@ -69,8 +80,13 @@ @Endpoint(id = "i18n") public class I18nEndpoint { + public static final String PROPERTY_SOURCE_NAME = "i18nEndpointPropertySource"; + private List serviceMessageSources; + @Autowired + private ConfigurableEnvironment environment; + @Autowired @Qualifier(SERVICE_MESSAGE_SOURCE_BEAN_NAME) public void initServiceMessageSources(ServiceMessageSource serviceMessageSource) { @@ -147,6 +163,59 @@ public List> getMessage(@Selector String code, @Selector Loc return messageMaps; } + @WriteOperation + public Map addMessage(String source, Locale locale, String code, String message) throws IOException { + PropertySourcesServiceMessageSource serviceMessageSource = getPropertySourcesServiceMessageSource(source); + Properties properties = loadProperties(serviceMessageSource, locale); + // Add a new code with message + properties.setProperty(code, message); + + String propertyName = serviceMessageSource.getPropertyName(locale); + StringWriter stringWriter = new StringWriter(); + // Properties -> StringWriter + properties.store(stringWriter, ""); + // StringWriter -> String + String propertyValue = stringWriter.toString(); + + MapPropertySource propertySource = getPropertySource(); + Map newProperties = propertySource.getSource(); + newProperties.put(propertyName, propertyValue); + + serviceMessageSource.init(); + return newProperties; + } + + private Properties loadProperties(PropertySourcesServiceMessageSource serviceMessageSource, Locale locale) throws IOException { + Properties properties = serviceMessageSource.loadAllProperties(locale); + return properties == null ? new Properties() : properties; + } + + private MapPropertySource getPropertySource() { + MutablePropertySources propertySources = environment.getPropertySources(); + String name = PROPERTY_SOURCE_NAME; + MapPropertySource propertySource = (MapPropertySource) propertySources.get(name); + if (propertySource == null) { + Map properties = new HashMap<>(); + propertySource = new MapPropertySource(name, properties); + propertySources.addFirst(propertySource); + } + return propertySource; + } + + private PropertySourcesServiceMessageSource getPropertySourcesServiceMessageSource(String source) { + return serviceMessageSources.stream() + .filter(serviceMessageSource -> + Objects.equals(source, serviceMessageSource.getSource())) + .filter(this::isPropertySourcesServiceMessageSource) + .map(PropertySourcesServiceMessageSource.class::cast) + .findFirst() + .get(); + } + + private boolean isPropertySourcesServiceMessageSource(ServiceMessageSource serviceMessageSource) { + return serviceMessageSource instanceof PropertySourcesServiceMessageSource; + } + private String getResource(ServiceMessageSource serviceMessageSource, Locale locale) { String resource = null; if (serviceMessageSource instanceof AbstractResourceServiceMessageSource) { diff --git a/microsphere-i18n-spring/src/main/java/io/microsphere/i18n/spring/PropertySourcesServiceMessageSource.java b/microsphere-i18n-spring/src/main/java/io/microsphere/i18n/spring/PropertySourcesServiceMessageSource.java index 166fb30..1ae97ba 100644 --- a/microsphere-i18n-spring/src/main/java/io/microsphere/i18n/spring/PropertySourcesServiceMessageSource.java +++ b/microsphere-i18n-spring/src/main/java/io/microsphere/i18n/spring/PropertySourcesServiceMessageSource.java @@ -46,11 +46,27 @@ protected Locale getInternalLocale() { @Override protected List loadAllPropertiesResources(String resource) throws IOException { - String propertyName = resource; - String propertiesContent = environment.getProperty(propertyName); + String propertiesContent = getPropertiesContent(resource); return hasText(propertiesContent) ? asList(new StringReader(propertiesContent)) : emptyList(); } + protected String getPropertiesContent(String resource) { + String propertyName = getPropertyName(resource); + String propertiesContent = environment.getProperty(propertyName); + return propertiesContent; + } + + public String getPropertyName(Locale locale) { + String resource = getResource(locale); + String propertyName = getPropertyName(resource); + return propertyName; + } + + protected String getPropertyName(String resource) { + String propertyName = resource; + return propertyName; + } + @Override public void setEnvironment(Environment environment) { this.environment = environment;