package org.dcm4chee.conf;
import org.dcm4che3.conf.core.api.ConfigurableClass;
import org.dcm4che3.conf.core.api.ConfigurableClassExtension;
import org.dcm4che3.conf.core.util.Extensions;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javax.enterprise.context.ApplicationScoped;
import javax.enterprise.inject.Instance;
import javax.inject.Inject;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
@ApplicationScoped
public class ConfigurableExtensionsResolver {
private final static Logger log = LoggerFactory.getLogger(ConfigurableExtensionsResolver.class);
@Inject
private Instance<ConfigurableClassExtension<?>> allExtensions;
/**
* To avoid logging warning multiple times
*/
private boolean loggedWarnings = false;
public List<Class> resolveExtensionsList() {
List<Class> list = new ArrayList<>();
for (ConfigurableClassExtension extension : getAllConfigurableExtensions())
if (!list.contains(extension.getClass()))
list.add(extension.getClass());
return list;
}
public Map<Class, List<Class>> resolveExtensionsMap(boolean doLog) {
Map<Class, List<Class>> extByBaseExtMap = Extensions.getAMapOfExtensionsByBaseExtension(getAllConfigurableExtensions());
if (doLog) {
String extensionsLog = "";
for (Map.Entry<Class, List<Class>> classListEntry : extByBaseExtMap.entrySet()) {
extensionsLog += "\nExtension classes of " + classListEntry.getKey().getSimpleName() + ":\n";
for (Class aClass : classListEntry.getValue())
extensionsLog += aClass.getName() + "\n";
}
extensionsLog += "\n";
log.info(extensionsLog);
}
return extByBaseExtMap;
}
/**
* @return all extension classes that have a ConfigurableClass annotation
*/
private List<ConfigurableClassExtension> getAllConfigurableExtensions() {
List<ConfigurableClassExtension> configurableExtensions = new ArrayList<>();
for (ConfigurableClassExtension extension : allExtensions) {
if (extension.getClass().getAnnotation(ConfigurableClass.class) != null)
configurableExtensions.add(extension);
}
// make sure simple class names are unique
HashSet<String> simpleNames = new HashSet<>();
HashSet<String> fullNames = new HashSet<>();
for (ConfigurableClassExtension configurableExtension : configurableExtensions) {
String simpleName = configurableExtension.getClass().getSimpleName();
String fullName = configurableExtension.getClass().getName();
boolean simpleNameExisted = !simpleNames.add(simpleName);
boolean fullNameExisted = !fullNames.add(fullName);
if (simpleNameExisted && !fullNameExisted) {
// we have a duplicate, let's find out all occurrences
List<ConfigurableClassExtension> conflicting = configurableExtensions.stream()
.filter((ext) -> ext.getClass().getSimpleName().equals(simpleName))
.collect(Collectors.toList());
throw new IllegalArgumentException("Simple class names of configurable extensions MUST be unique. This rule was violated by classes:\n" + conflicting);
} else if (simpleNameExisted && fullNameExisted) {
// if fullname existed as well, it means we have a class with the same name
// could happen when deploying duplicate libs, etc, so not as critical, just print a warning
if (!loggedWarnings) log.warn("Found duplicate configurable extension class: " + fullName);
}
}
loggedWarnings = true;
return configurableExtensions;
}
}