/**
* Copyright (c) 2013-2016, The SeedStack authors <http://seedstack.org>
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/
package org.seedstack.seed.core;
import com.fasterxml.jackson.dataformat.yaml.YAMLMapper;
import io.nuun.kernel.api.Plugin;
import org.seedstack.coffig.Coffig;
import org.seedstack.coffig.provider.CompositeProvider;
import org.seedstack.coffig.provider.InMemoryProvider;
import org.seedstack.coffig.spi.ConfigurationProvider;
import org.seedstack.seed.ApplicationConfig;
import org.seedstack.seed.core.internal.configuration.ConfigurationPriority;
import org.seedstack.seed.core.internal.configuration.PrioritizedProvider;
import org.seedstack.seed.diagnostic.DiagnosticManager;
import org.seedstack.seed.diagnostic.spi.DiagnosticInfoCollector;
import javax.annotation.Nullable;
import javax.validation.ValidatorFactory;
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.ServiceLoader;
import java.util.Set;
public class SeedRuntime {
private static final String SEED_PACKAGE_PREFIX = "org.seedstack.seed";
private static final YAMLMapper yamlMapper = new YAMLMapper();
private final Object context;
private final DiagnosticManager diagnosticManager;
private final Coffig configuration;
private final InMemoryProvider inMemoryProvider;
private final PrioritizedProvider prioritizedProvider;
private final ValidatorFactory validatorFactory;
private final String seedVersion;
private final String businessVersion;
private final ApplicationConfig applicationConfig;
private final Set<String> inconsistentPlugins = new HashSet<>();
private SeedRuntime(Object context, DiagnosticManager diagnosticManager, Coffig configuration, ValidatorFactory validatorFactory, String seedVersion, String businessVersion, ApplicationConfig applicationConfig) {
this.context = context;
this.diagnosticManager = diagnosticManager;
this.configuration = configuration;
this.validatorFactory = validatorFactory;
this.seedVersion = seedVersion;
this.businessVersion = businessVersion;
this.applicationConfig = applicationConfig;
this.diagnosticManager.registerDiagnosticInfoCollector("seed", new RuntimeDiagnosticCollector());
this.prioritizedProvider = ((CompositeProvider) this.configuration.getProvider()).get(PrioritizedProvider.class);
this.inMemoryProvider = new InMemoryProvider();
registerConfigurationProvider(this.inMemoryProvider, ConfigurationPriority.DEFAULT);
checkConsistency();
}
public <T> T contextAs(Class<T> tClass) {
if (context != null && tClass.isAssignableFrom(context.getClass())) {
return tClass.cast(context);
} else {
return null;
}
}
public DiagnosticManager getDiagnosticManager() {
return diagnosticManager;
}
public Coffig getConfiguration() {
return configuration;
}
public void registerConfigurationProvider(ConfigurationProvider configurationProvider, int priority) {
prioritizedProvider.registerProvider(configurationProvider, priority);
}
public void setDefaultConfiguration(String key, String value) {
inMemoryProvider.put(key, value);
}
public void setDefaultConfiguration(String key, String... values) {
inMemoryProvider.put(key, values);
}
public void setDefaultConfiguration(String key, Collection<String> values) {
inMemoryProvider.put(key, values);
}
public ValidatorFactory getValidatorFactory() {
return validatorFactory;
}
public String getVersion() {
return seedVersion;
}
public String getBusinessVersion() {
return businessVersion;
}
public ApplicationConfig getApplicationConfig() {
return applicationConfig;
}
private void checkConsistency() {
if (seedVersion != null) {
for (Plugin plugin : ServiceLoader.load(Plugin.class)) {
Class<? extends Plugin> pluginClass = plugin.getClass();
Package pluginPackage = pluginClass.getPackage();
if (pluginPackage != null && pluginPackage.getName().startsWith(SEED_PACKAGE_PREFIX)) {
String pluginVersion = pluginPackage.getImplementationVersion();
if (!seedVersion.equals(pluginVersion)) {
inconsistentPlugins.add(plugin.name());
}
}
}
}
}
public static class Builder {
private Object _context;
private Coffig _configuration;
private DiagnosticManager _diagnosticManager;
private ValidatorFactory _validatorFactory;
private String _seedVersion;
private String _businessVersion;
private ApplicationConfig _applicationConfig;
private Builder() {
}
public Builder context(Object context) {
this._context = context;
return this;
}
public Builder configuration(Coffig configuration) {
this._configuration = configuration;
return this;
}
public Builder diagnosticManager(DiagnosticManager diagnosticManager) {
this._diagnosticManager = diagnosticManager;
return this;
}
public Builder validatorFactory(ValidatorFactory validatorFactory) {
this._validatorFactory = validatorFactory;
return this;
}
public Builder version(@Nullable String seedVersion) {
this._seedVersion = seedVersion;
return this;
}
public Builder businessVersion(String businessVersion) {
this._businessVersion = businessVersion;
return this;
}
public Builder applicationConfig(ApplicationConfig applicationConfig) {
this._applicationConfig = applicationConfig;
return this;
}
public SeedRuntime build() {
return new SeedRuntime(_context, _diagnosticManager, _configuration, _validatorFactory, _seedVersion, _businessVersion, _applicationConfig);
}
}
public static Builder builder() {
return new Builder();
}
private class RuntimeDiagnosticCollector implements DiagnosticInfoCollector {
@Override
public Map<String, Object> collect() {
Map<String, Object> result = new HashMap<>();
result.put("version", seedVersion == null ? "UNKNOWN" : seedVersion);
result.put("businessVersion", businessVersion == null ? "UNKNOWN" : businessVersion);
result.put("inconsistentPlugins", inconsistentPlugins);
result.put("contextClass", context == null ? "NONE" : context.getClass().getName());
try {
result.put("configuration", yamlMapper.readValue(configuration.toString(), Map.class));
} catch (Exception e) {
result.put("rawConfiguration", configuration.toString());
}
return result;
}
}
}