Skip to content

Commit

Permalink
[i18n] Refactoring and annotations (openhab#1161)
Browse files Browse the repository at this point in the history
* Added nullness annotations to 'RuleTemplateI18nUtil'
* Added nullness annotations to 'ConfigDescriptionGroupI18nUtil'
* Moved 'ConfigDescriptionI18nUtil' into internal package
* Moved 'ConfigDescriptionGroupI18nUtil' into internal package
* Moved 'ThingTypeI18nUtil' into internal package
* Use 'ConfigI18nLocalizationService' instead of 'ConfigDescriptionI18nUtil'
* Use default labels / descriptions if application of localization is not successful
* Resolved itest.bndrun files

Signed-off-by: Christoph Weitkamp <github@christophweitkamp.de>
  • Loading branch information
cweitkamp authored and wborn committed Oct 27, 2019
1 parent d39b6bd commit 12d91f7
Show file tree
Hide file tree
Showing 19 changed files with 204 additions and 209 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -30,16 +30,14 @@
import java.util.Map.Entry;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import java.util.stream.Collectors;

import org.eclipse.jdt.annotation.NonNullByDefault;
import org.eclipse.jdt.annotation.Nullable;
import org.eclipse.smarthome.config.core.ConfigDescriptionParameter;
import org.eclipse.smarthome.config.core.ConfigDescriptionParameterBuilder;
import org.eclipse.smarthome.config.core.ParameterOption;
import org.eclipse.smarthome.config.core.i18n.ConfigDescriptionI18nUtil;
import org.eclipse.smarthome.config.core.i18n.ConfigI18nLocalizationService;
import org.eclipse.smarthome.core.common.registry.Provider;
import org.eclipse.smarthome.core.common.registry.ProviderChangeListener;
import org.eclipse.smarthome.core.i18n.TranslationProvider;
import org.openhab.core.automation.Rule;
import org.openhab.core.automation.parser.Parser;
import org.openhab.core.automation.parser.ParsingException;
Expand Down Expand Up @@ -83,10 +81,7 @@ public AbstractResourceBundleProvider(String path) {
*/
protected static final String ROOT_DIRECTORY = "ESH-INF/automation";

/**
* This field holds a reference to the service instance for internationalization support within the platform.
*/
protected @NonNullByDefault({}) TranslationProvider i18nProvider;
protected @Nullable ConfigI18nLocalizationService configI18nService;

/**
* This field keeps instance of {@link Logger} that is used for logging.
Expand Down Expand Up @@ -215,14 +210,6 @@ protected void removeParser(Parser<E> parser, Map<String, String> properties) {
parsers.remove(parserType);
}

protected void setTranslationProvider(TranslationProvider i18nProvider) {
this.i18nProvider = i18nProvider;
}

protected void unsetTranslationProvider(TranslationProvider i18nProvider) {
this.i18nProvider = null;
}

/**
* This method provides common functionality for {@link ModuleTypeProvider} and {@link TemplateProvider} to process
* the bundles. For {@link RuleResourceBundleImporter} this method is overridden.
Expand Down Expand Up @@ -386,60 +373,22 @@ protected void processAutomationProviderUninstalled(Bundle bundle) {
return null;
}

protected List<ConfigDescriptionParameter> getLocalizedConfigurationDescription(TranslationProvider i18nProvider,
protected List<ConfigDescriptionParameter> getLocalizedConfigurationDescription(
@Nullable List<ConfigDescriptionParameter> config, Bundle bundle, String uid, String prefix,
@Nullable Locale locale) {
List<ConfigDescriptionParameter> configDescriptions = new ArrayList<>();
if (config != null) {
ConfigDescriptionI18nUtil util = new ConfigDescriptionI18nUtil(i18nProvider);
for (ConfigDescriptionParameter parameter : config) {
String parameterName = parameter.getName();
URI uri = null;
try {
uri = new URI(prefix + ":" + uid + ".name");
} catch (URISyntaxException e) {
logger.error("Constructed invalid uri '{}:{}.name'", prefix, uid, e);
return Collections.emptyList();
}
String llabel = parameter.getLabel();
if (llabel != null) {
llabel = util.getParameterLabel(bundle, uri, parameterName, llabel, locale);
}
String ldescription = parameter.getDescription();
if (ldescription != null) {
ldescription = util.getParameterDescription(bundle, uri, parameterName, ldescription, locale);
}
String lpattern = parameter.getPattern();
if (lpattern != null) {
lpattern = util.getParameterPattern(bundle, uri, parameterName, lpattern, locale);
}
List<ParameterOption> loptions = parameter.getOptions();
if (loptions != null && !loptions.isEmpty()) {
for (ParameterOption option : loptions) {
String label = util.getParameterOptionLabel(bundle, uri, parameterName, option.getValue(),
option.getLabel(), locale);
option = new ParameterOption(option.getValue(), label);
}
}
String lunitLabel = parameter.getUnitLabel();
if (lunitLabel != null) {
lunitLabel = util.getParameterUnitLabel(bundle, uri, parameterName, parameter.getUnit(), lunitLabel,
locale);
}
configDescriptions.add(ConfigDescriptionParameterBuilder.create(parameterName, parameter.getType())
.withMinimum(parameter.getMinimum()).withMaximum(parameter.getMaximum())
.withStepSize(parameter.getStepSize()).withPattern(lpattern)
.withRequired(parameter.isRequired()).withMultiple(parameter.isMultiple())
.withReadOnly(parameter.isReadOnly()).withContext(parameter.getContext())
.withDefault(parameter.getDefault()).withLabel(llabel).withDescription(ldescription)
.withFilterCriteria(parameter.getFilterCriteria()).withGroupName(parameter.getGroupName())
.withAdvanced(parameter.isAdvanced()).withOptions(loptions)
.withLimitToOptions(parameter.getLimitToOptions())
.withMultipleLimit(parameter.getMultipleLimit()).withUnit(parameter.getUnit())
.withUnitLabel(lunitLabel).build());
ConfigI18nLocalizationService localConfigI18nService = configI18nService;
if (config != null && localConfigI18nService != null) {
try {
URI uri = new URI(prefix + ":" + uid + ".name");
return config.stream()
.map(p -> localConfigI18nService.getLocalizedConfigDescriptionParameter(bundle, uri, p, locale))
.collect(Collectors.toList());
} catch (URISyntaxException e) {
logger.error("Constructed invalid uri '{}:{}.name'", prefix, uid, e);
return config;
}
}
return configDescriptions;
return Collections.emptyList();
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,6 @@
import org.eclipse.jdt.annotation.Nullable;
import org.eclipse.smarthome.core.common.registry.Provider;
import org.eclipse.smarthome.core.common.registry.ProviderChangeListener;
import org.eclipse.smarthome.core.i18n.TranslationProvider;
import org.openhab.core.automation.module.provider.i18n.ModuleTypeI18nService;
import org.openhab.core.automation.parser.Parser;
import org.openhab.core.automation.type.ModuleType;
Expand Down Expand Up @@ -92,17 +91,6 @@ protected void removeParser(Parser<ModuleType> parser, Map<String, String> prope
super.removeParser(parser, properties);
}

@Override
@Reference(cardinality = ReferenceCardinality.OPTIONAL, policy = ReferencePolicy.DYNAMIC)
protected void setTranslationProvider(TranslationProvider i18nProvider) {
super.setTranslationProvider(i18nProvider);
}

@Override
protected void unsetTranslationProvider(TranslationProvider i18nProvider) {
super.unsetTranslationProvider(i18nProvider);
}

@Override
public Collection<ModuleType> getAll() {
return providedObjectsHolder.values();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
import org.eclipse.jdt.annotation.NonNullByDefault;
import org.eclipse.jdt.annotation.Nullable;
import org.eclipse.smarthome.config.core.ConfigDescriptionParameter;
import org.eclipse.smarthome.config.core.i18n.ConfigI18nLocalizationService;
import org.eclipse.smarthome.core.common.registry.Provider;
import org.eclipse.smarthome.core.common.registry.ProviderChangeListener;
import org.eclipse.smarthome.core.i18n.TranslationProvider;
Expand Down Expand Up @@ -66,14 +67,22 @@
public class TemplateResourceBundleProvider extends AbstractResourceBundleProvider<RuleTemplate>
implements RuleTemplateProvider {

private final RuleTemplateI18nUtil ruleTemplateI18nUtil;
private final ModuleI18nUtil moduleI18nUtil;

/**
* This constructor is responsible for initializing the path to resources and tracking the managing service of the
* {@link ModuleType}s and the managing service of the {@link RuleTemplates}s.
*
* @param context is the {@code BundleContext}, used for creating a tracker for {@link Parser} services.
*/
public TemplateResourceBundleProvider() {
@Activate
public TemplateResourceBundleProvider(final @Reference ConfigI18nLocalizationService configI18nService,
final @Reference TranslationProvider i18nProvider) {
super(ROOT_DIRECTORY + "/templates/");
this.configI18nService = configI18nService;
this.ruleTemplateI18nUtil = new RuleTemplateI18nUtil(i18nProvider);
this.moduleI18nUtil = new ModuleI18nUtil(i18nProvider);
}

@Override
Expand All @@ -99,17 +108,6 @@ protected void removeParser(Parser<RuleTemplate> parser, Map<String, String> pro
super.removeParser(parser, properties);
}

@Override
@Reference(cardinality = ReferenceCardinality.OPTIONAL, policy = ReferencePolicy.DYNAMIC)
protected void setTranslationProvider(TranslationProvider i18nProvider) {
super.setTranslationProvider(i18nProvider);
}

@Override
protected void unsetTranslationProvider(TranslationProvider i18nProvider) {
super.unsetTranslationProvider(i18nProvider);
}

@Override
public Collection<RuleTemplate> getAll() {
return providedObjectsHolder.values();
Expand Down Expand Up @@ -160,26 +158,26 @@ public Collection<RuleTemplate> getTemplates(@Nullable Locale locale) {
* @return the localized {@link Template}.
*/
private @Nullable RuleTemplate getPerLocale(@Nullable RuleTemplate defTemplate, @Nullable Locale locale) {
if (locale == null || defTemplate == null || i18nProvider == null) {
if (locale == null || defTemplate == null) {
return defTemplate;
}
String uid = defTemplate.getUID();
Bundle bundle = getBundle(uid);

if (bundle != null && defTemplate instanceof RuleTemplate) {
String llabel = RuleTemplateI18nUtil.getLocalizedRuleTemplateLabel(i18nProvider, bundle, uid,
defTemplate.getLabel(), locale);
String ldescription = RuleTemplateI18nUtil.getLocalizedRuleTemplateDescription(i18nProvider, bundle, uid,
String llabel = ruleTemplateI18nUtil.getLocalizedRuleTemplateLabel(bundle, uid, defTemplate.getLabel(),
locale);
String ldescription = ruleTemplateI18nUtil.getLocalizedRuleTemplateDescription(bundle, uid,
defTemplate.getDescription(), locale);
List<ConfigDescriptionParameter> lconfigDescriptions = getLocalizedConfigurationDescription(i18nProvider,
List<ConfigDescriptionParameter> lconfigDescriptions = getLocalizedConfigurationDescription(
defTemplate.getConfigurationDescriptions(), bundle, uid, RuleTemplateI18nUtil.RULE_TEMPLATE,
locale);
List<Action> lactions = ModuleI18nUtil.getLocalizedModules(i18nProvider, defTemplate.getActions(), bundle,
uid, RuleTemplateI18nUtil.RULE_TEMPLATE, locale);
List<Condition> lconditions = ModuleI18nUtil.getLocalizedModules(i18nProvider, defTemplate.getConditions(),
bundle, uid, RuleTemplateI18nUtil.RULE_TEMPLATE, locale);
List<Trigger> ltriggers = ModuleI18nUtil.getLocalizedModules(i18nProvider, defTemplate.getTriggers(),
bundle, uid, RuleTemplateI18nUtil.RULE_TEMPLATE, locale);
List<Action> lactions = moduleI18nUtil.getLocalizedModules(defTemplate.getActions(), bundle, uid,
RuleTemplateI18nUtil.RULE_TEMPLATE, locale);
List<Condition> lconditions = moduleI18nUtil.getLocalizedModules(defTemplate.getConditions(), bundle, uid,
RuleTemplateI18nUtil.RULE_TEMPLATE, locale);
List<Trigger> ltriggers = moduleI18nUtil.getLocalizedModules(defTemplate.getTriggers(), bundle, uid,
RuleTemplateI18nUtil.RULE_TEMPLATE, locale);
return new RuleTemplate(uid, llabel, ldescription, defTemplate.getTags(), ltriggers, lconditions, lactions,
lconfigDescriptions, defTemplate.getVisibility());
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,13 +36,19 @@
@NonNullByDefault
public class ModuleI18nUtil {

public static <T extends Module> List<T> getLocalizedModules(TranslationProvider i18nProvider, List<T> modules,
Bundle bundle, String uid, String prefix, @Nullable Locale locale) {
private final TranslationProvider i18nProvider;

public ModuleI18nUtil(TranslationProvider i18nProvider) {
this.i18nProvider = i18nProvider;
}

public <T extends Module> List<T> getLocalizedModules(List<T> modules, Bundle bundle, String uid, String prefix,
@Nullable Locale locale) {
List<T> lmodules = new ArrayList<>();
for (T module : modules) {
String label = getModuleLabel(i18nProvider, bundle, uid, module.getId(), module.getLabel(), prefix, locale);
String description = getModuleDescription(i18nProvider, bundle, uid, module.getId(),
module.getDescription(), prefix, locale);
String label = getModuleLabel(bundle, uid, module.getId(), module.getLabel(), prefix, locale);
String description = getModuleDescription(bundle, uid, module.getId(), module.getDescription(), prefix,
locale);
@Nullable
T lmodule = createLocalizedModule(module, label, description);
lmodules.add(lmodule == null ? module : lmodule);
Expand All @@ -51,7 +57,7 @@ public static <T extends Module> List<T> getLocalizedModules(TranslationProvider
}

@SuppressWarnings("unchecked")
private static <T extends Module> @Nullable T createLocalizedModule(T module, @Nullable String label,
private <T extends Module> @Nullable T createLocalizedModule(T module, @Nullable String label,
@Nullable String description) {
if (module instanceof Action) {
return (T) createLocalizedAction((Action) module, label, description);
Expand All @@ -65,34 +71,32 @@ public static <T extends Module> List<T> getLocalizedModules(TranslationProvider
return null;
}

private static Trigger createLocalizedTrigger(Trigger module, @Nullable String label,
@Nullable String description) {
private Trigger createLocalizedTrigger(Trigger module, @Nullable String label, @Nullable String description) {
return ModuleBuilder.createTrigger(module).withLabel(label).withDescription(description).build();
}

private static Condition createLocalizedCondition(Condition module, @Nullable String label,
@Nullable String description) {
private Condition createLocalizedCondition(Condition module, @Nullable String label, @Nullable String description) {
return ModuleBuilder.createCondition(module).withLabel(label).withDescription(description).build();
}

private static Action createLocalizedAction(Action module, @Nullable String label, @Nullable String description) {
private Action createLocalizedAction(Action module, @Nullable String label, @Nullable String description) {
return ModuleBuilder.createAction(module).withLabel(label).withDescription(description).build();
}

private static @Nullable String getModuleLabel(TranslationProvider i18nProvider, Bundle bundle, String uid,
String moduleName, @Nullable String defaultLabel, String prefix, @Nullable Locale locale) {
private @Nullable String getModuleLabel(Bundle bundle, String uid, String moduleName, @Nullable String defaultLabel,
String prefix, @Nullable Locale locale) {
String key = I18nUtil.stripConstantOr(defaultLabel, () -> inferModuleKey(prefix, uid, moduleName, "label"));
return i18nProvider.getText(bundle, key, defaultLabel, locale);
}

private static @Nullable String getModuleDescription(TranslationProvider i18nProvider, Bundle bundle, String uid,
String moduleName, @Nullable String defaultDescription, String prefix, @Nullable Locale locale) {
private @Nullable String getModuleDescription(Bundle bundle, String uid, String moduleName,
@Nullable String defaultDescription, String prefix, @Nullable Locale locale) {
String key = I18nUtil.stripConstantOr(defaultDescription,
() -> inferModuleKey(prefix, uid, moduleName, "description"));
return i18nProvider.getText(bundle, key, defaultDescription, locale);
}

private static String inferModuleKey(String prefix, String uid, String moduleName, String lastSegment) {
private String inferModuleKey(String prefix, String uid, String moduleName, String lastSegment) {
return prefix + uid + ".input." + moduleName + "." + lastSegment;
}
}
Loading

0 comments on commit 12d91f7

Please sign in to comment.