/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*
*/
package com.github.rodionmoiseev.c10n;
import com.github.rodionmoiseev.c10n.formatters.MessageFormatter;
import com.github.rodionmoiseev.c10n.plugin.C10NPlugin;
import java.lang.annotation.Annotation;
import java.lang.reflect.Method;
import java.util.*;
/**
* @author rodion
*/
class DefaultConfiguredC10NModule implements ConfiguredC10NModule {
private final C10NConfigBase parentConfig;
private final ConfigChainResolver configResolver;
DefaultConfiguredC10NModule(C10NConfigBase parentConfig, ConfigChainResolver configResolver) {
this.parentConfig = parentConfig;
this.configResolver = configResolver;
}
@Override
public Locale getCurrentLocale() {
return this.parentConfig.getCurrentLocale();
}
@Override
public Map<Class<? extends Annotation>, Set<Locale>> getAnnotationBindings(Class<?> c10nInterface) {
Map<Class<? extends Annotation>, Set<Locale>> res = new HashMap<Class<? extends Annotation>, Set<Locale>>();
List<C10NConfigBase> configChain = configResolver.resolve(c10nInterface);
Collections.reverse(configChain);
for (C10NConfigBase config : configChain) {
//config chain is reversed (parent -> .. -> child) to
//make sure child configurations overwrite parent ones
//to take precedence
res.putAll(config.getAnnotationToLocaleMapping());
}
return res;
}
@Override
public Set<Locale> getImplementationBindings(Class<?> c10nInterface) {
Set<Locale> res = new HashSet<Locale>();
List<C10NConfigBase> configChain = configResolver.resolve(c10nInterface);
for (C10NConfigBase config : configChain) {
res.addAll(config.getImplLocales(c10nInterface));
}
return res;
}
@Override
public Class<?> getImplementationBinding(Class<?> c10nInterface, Locale locale) {
List<C10NConfigBase> configChain = configResolver.resolve(c10nInterface);
for (C10NConfigBase config : configChain) {
Class<?> impl = config.getBindingForLocale(c10nInterface, locale);
if (null != impl) {
return impl;
}
}
return null;
}
@Override
public List<ResourceBundle> getBundleBindings(Class<?> c10nInterface, Locale locale) {
List<ResourceBundle> res = new ArrayList<ResourceBundle>();
List<C10NConfigBase> configChain = configResolver.resolve(c10nInterface);
for (C10NConfigBase config : configChain) {
res.addAll(config.getBundlesForLocale(c10nInterface, locale));
}
return res;
}
@Override
public Map<AnnotatedClass, C10NFilterProvider<?>> getFilterBindings(Class<?> c10nInterface) {
List<C10NConfigBase> configChain = configResolver.resolve(c10nInterface);
Map<AnnotatedClass, C10NFilterProvider<?>> res = new HashMap<AnnotatedClass, C10NFilterProvider<?>>();
Collections.reverse(configChain);
for (C10NConfigBase config : configChain) {
for (C10NConfigBase.C10NFilterBinder<?> filterBinder : config.getFilterBinders()) {
if (filterBinder.getAnnotatedWith().isEmpty()) {
res.put(new AnnotatedClass(filterBinder.getType(), null), filterBinder.getFilterProvider());
} else {
for (Class<? extends Annotation> annotation : filterBinder.getAnnotatedWith()) {
res.put(new AnnotatedClass(filterBinder.getType(), annotation), filterBinder.getFilterProvider());
}
}
}
}
return res;
}
@Override
public String getUntranslatedMessageString(Class<?> c10nInterface, Method method, Object[] methodArgs) {
return parentConfig.getUntranslatedMessageString(c10nInterface, method, methodArgs);
}
@Override
public String getKeyPrefix() {
return this.parentConfig.getKeyPrefix();
}
@Override
public boolean isDebug() {
return this.parentConfig.isDebug();
}
@Override
public Set<Locale> getAllBoundLocales() {
Set<Locale> res = new HashSet<Locale>();
for (C10NConfigBase config : traverseConfigs(parentConfig)) {
res.addAll(config.getAllImplementationBoundLocales());
for (Set<Locale> locales : config.getAnnotationToLocaleMapping().values()) {
res.addAll(locales);
}
}
return res;
}
@Override
public List<C10NPlugin> getPlugins(){
List<C10NPlugin> plugins = new ArrayList<C10NPlugin>();
for (C10NConfigBase config : traverseConfigs(parentConfig)) {
plugins.addAll(config.getPlugins());
}
return plugins;
}
@Override
public MessageFormatter getMessageFormatter() {
return parentConfig.getMessageFormatter();
}
@Override
public ClassLoader getProxyClassLoader() {
return parentConfig.getProxyClassLoader();
}
private List<C10NConfigBase> traverseConfigs(C10NConfigBase config) {
List<C10NConfigBase> res = new ArrayList<C10NConfigBase>();
traverseConfigs(config, res);
return res;
}
private void traverseConfigs(C10NConfigBase config, List<C10NConfigBase> result) {
result.add(config);
for (C10NConfigBase childConfig : config.getChildConfigs()) {
traverseConfigs(childConfig, result);
}
}
}