/*
* Copyright 2017 TNG Technology Consulting GmbH
*
* Licensed 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.tngtech.archunit;
import java.io.IOException;
import java.io.InputStream;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import com.google.common.base.Splitter;
import com.google.common.base.Supplier;
import com.google.common.base.Suppliers;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
import com.tngtech.archunit.base.Optional;
import com.tngtech.archunit.core.importer.resolvers.ClassResolver;
import static com.tngtech.archunit.PublicAPI.Usage.ACCESS;
public final class ArchConfiguration {
@Internal // {@value ...} doesn't work on non public constants outside of the package
public static final String ARCHUNIT_PROPERTIES_RESOURCE_NAME = "/archunit.properties";
static final String RESOLVE_MISSING_DEPENDENCIES_FROM_CLASS_PATH = "resolveMissingDependenciesFromClassPath";
static final String CLASS_RESOLVER = "classResolver";
static final String CLASS_RESOLVER_ARGS = "classResolver.args";
@Internal
public static final String ENABLE_MD5_IN_CLASS_SOURCES = "enableMd5InClassSources";
private static final Map<String, String> PROPERTY_DEFAULTS = ImmutableMap.of(
RESOLVE_MISSING_DEPENDENCIES_FROM_CLASS_PATH, "" + false,
ENABLE_MD5_IN_CLASS_SOURCES, "" + false
);
private static final Supplier<ArchConfiguration> INSTANCE = Suppliers.memoize(new Supplier<ArchConfiguration>() {
@Override
public ArchConfiguration get() {
return new ArchConfiguration();
}
});
@PublicAPI(usage = ACCESS)
public static ArchConfiguration get() {
return INSTANCE.get();
}
private final String propertiesResourceName;
private boolean resolveMissingDependenciesFromClassPath;
private Optional<String> classResolver = Optional.absent();
private List<String> classResolverArguments = Collections.emptyList();
private boolean enableMd5InClassSources;
private ArchConfiguration() {
this(ARCHUNIT_PROPERTIES_RESOURCE_NAME);
}
private ArchConfiguration(String propertiesResourceName) {
this.propertiesResourceName = propertiesResourceName;
readProperties(propertiesResourceName);
}
private void readProperties(String propertiesResourceName) {
Properties properties = new Properties();
try (InputStream inputStream = getClass().getResourceAsStream(propertiesResourceName)) {
if (inputStream != null) {
properties.load(inputStream);
}
} catch (IOException ignore) {
}
set(properties);
}
@PublicAPI(usage = ACCESS)
public void reset() {
readProperties(propertiesResourceName);
}
@PublicAPI(usage = ACCESS)
public boolean resolveMissingDependenciesFromClassPath() {
return resolveMissingDependenciesFromClassPath;
}
@PublicAPI(usage = ACCESS)
public void setResolveMissingDependenciesFromClassPath(boolean newValue) {
resolveMissingDependenciesFromClassPath = newValue;
}
private void set(Properties properties) {
resolveMissingDependenciesFromClassPath = Boolean.valueOf(
propertyOrDefault(properties, RESOLVE_MISSING_DEPENDENCIES_FROM_CLASS_PATH));
classResolver = Optional.fromNullable(properties.getProperty(CLASS_RESOLVER));
classResolverArguments = Splitter.on(",").trimResults().omitEmptyStrings()
.splitToList(properties.getProperty(CLASS_RESOLVER_ARGS, ""));
enableMd5InClassSources = Boolean.valueOf(
propertyOrDefault(properties, ENABLE_MD5_IN_CLASS_SOURCES));
}
@PublicAPI(usage = ACCESS)
public boolean md5InClassSourcesEnabled() {
return enableMd5InClassSources;
}
@PublicAPI(usage = ACCESS)
public void setMd5InClassSourcesEnabled(boolean enabled) {
this.enableMd5InClassSources = enabled;
}
@PublicAPI(usage = ACCESS)
public Optional<String> getClassResolver() {
return classResolver;
}
@PublicAPI(usage = ACCESS)
public void setClassResolver(Class<? extends ClassResolver> classResolver) {
this.classResolver = Optional.of(classResolver.getName());
}
@PublicAPI(usage = ACCESS)
public void unsetClassResolver() {
this.classResolver = Optional.absent();
}
@PublicAPI(usage = ACCESS)
public List<String> getClassResolverArguments() {
return classResolverArguments;
}
@PublicAPI(usage = ACCESS)
public void setClassResolverArguments(String... args) {
classResolverArguments = ImmutableList.copyOf(args);
}
private String propertyOrDefault(Properties properties, String propertyName) {
return properties.getProperty(propertyName, PROPERTY_DEFAULTS.get(propertyName));
}
}