You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

96 lines
3.1 KiB

8 years ago
package de.joshavg.simpledic;
import de.joshavg.simpledic.exception.ClassNotRegistered;
8 years ago
import de.joshavg.simpledic.exception.ContainerInitException;
import de.joshavg.simpledic.exception.SdicInstantiationException;
8 years ago
import java.io.IOException;
import java.io.InputStream;
import java.lang.reflect.InvocationTargetException;
8 years ago
import java.util.HashMap;
8 years ago
import java.util.List;
8 years ago
import java.util.Map;
import java.util.Objects;
8 years ago
import java.util.Properties;
import java.util.stream.Collectors;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
8 years ago
8 years ago
public class SdiContainer implements SdiContainerInterface {
8 years ago
private static final Logger LOG = LoggerFactory.getLogger(SdiContainer.class);
8 years ago
private final Properties props;
private final List<ServiceDefinition> definitions;
8 years ago
private final Map<Class<?>, Object> singletons;
8 years ago
private SdiContainer(Properties props, List<ServiceDefinition> definitions) {
8 years ago
this.props = props;
this.definitions = definitions;
8 years ago
this.singletons = new HashMap<>();
8 years ago
}
public static SdiContainer load() {
return load("sdic.properties");
}
public static SdiContainer load(String filename) {
Properties props = new Properties();
InputStream inputStream = SdiContainer.class.getClassLoader().getResourceAsStream(filename);
if (inputStream == null) {
throw new ContainerInitException("config file " + filename + " not found", null);
}
8 years ago
try {
props.load(inputStream);
} catch (IOException e) {
throw new ContainerInitException("failed loading properties", e);
}
IntegrityCheck integrityCheck = new IntegrityCheck(props);
integrityCheck.check();
return new SdiContainer(props, integrityCheck.getDefinitions());
8 years ago
}
private List<Class<?>> serviceClasses() {
return definitions.stream().map(ServiceDefinition::getClz).collect(Collectors.toList());
8 years ago
}
8 years ago
@Override
public <T> T getInstance(Class<T> clz) {
LOG.trace("instance ordered: ", clz);
if (!serviceClasses().contains(clz)) {
throw new ClassNotRegistered(clz);
8 years ago
}
8 years ago
if (isStoredAsSingleton(clz)) {
return clz.cast(singletons.get(clz));
}
try {
8 years ago
T instance = new Instantiator<>(clz, this).createInstance();
handleSingleton(clz, instance);
return instance;
} catch (IllegalAccessException | InvocationTargetException | InstantiationException e) {
throw new SdicInstantiationException(e);
}
8 years ago
}
8 years ago
private <T> void handleSingleton(Class<T> clz, T instance) {
String key = props.entrySet().stream()
.filter(e -> Objects.equals(clz.getName(), String.valueOf(e.getValue())))
.map(e -> e.getKey().toString())
.findFirst()
.orElse("");
if (props.containsKey(key + ".singleton") && "true".equals(props.get(key + ".singleton"))) {
singletons.put(clz, instance);
}
}
private <T> boolean isStoredAsSingleton(Class<T> clz) {
return singletons.containsKey(clz);
}
8 years ago
}