| 
						
						
							
								
							
						
						
					 | 
				
			
			 | 
			 | 
			
				@ -10,9 +10,28 @@ import java.util.HashMap;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				import java.util.List;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				import java.util.Map;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				import java.util.Properties;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				import java.util.stream.Collectors;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				import org.slf4j.Logger;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				import org.slf4j.LoggerFactory;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				/**
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				 * The main container that loads a specific properties file
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				 * and creates instances of defined services
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				 * <p>
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				 * Services are given arbitrary names and can be defined as singletons:
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				 * <code><pre>
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				 * service.servicename: tld.vendor.project.ServiceClass
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				 * service.servicename.singleton: true
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				 * </pre></code>
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				 * Service names must match the regular expression <code>^service\.[^.]+$</code>
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				 * <p>
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				 * Services declare their dependencies via their constructor. Only one
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				 * constructor per class is allowed.
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				 * All dependencies must be declared in the same container as the declaring
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				 * service.
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				 * <p>
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				 * After loading the properties file, an {@link IntegrityCheck} will be performed.
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				 */
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				public class SdiContainer implements SdiContainerInterface {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    private static final Logger LOG = LoggerFactory.getLogger(SdiContainer.class);
 | 
			
		
		
	
	
		
			
				
					| 
						
						
						
							
								
							
						
					 | 
				
			
			 | 
			 | 
			
				@ -25,11 +44,22 @@ public class SdiContainer implements SdiContainerInterface {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        this.singletons = new HashMap<>();
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    }
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    /**
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				     * Creates a Container using the file <code>sdic.properties</code> from the classpath.
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				     *
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				     * @return the loaded and integrity checked container
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				     */
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    @SuppressWarnings("unused")
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    public static SdiContainer load() {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        return load("sdic.properties");
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    }
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    /**
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				     * Creates a Container using the properties file at the designated location
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				     *
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				     * @param filename the filename that shall be loaded
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				     * @return the loaded and integrity checked container
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				     */
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    @SuppressWarnings("WeakerAccess")
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    public static SdiContainer load(String filename) {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        Properties props = new Properties();
 | 
			
		
		
	
	
		
			
				
					| 
						
							
								
							
						
						
							
								
							
						
						
					 | 
				
			
			 | 
			 | 
			
				@ -57,6 +87,16 @@ public class SdiContainer implements SdiContainerInterface {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				            .orElse(null);
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    }
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    /**
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				     * Creates and returns a service instance of the given class
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				     * <p>
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				     * Dependency services are automatically created. Services marked
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				     * as singletons will be only created once, either as transient
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				     * or direct dependency.
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				     *
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				     * @param clz the type which shall be created
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				     * @return the created type with declared dependencies fulfilled
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				     */
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    @Override
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    public <T> T getInstance(Class<T> clz) {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        LOG.trace("instance ordered: ", clz);
 | 
			
		
		
	
	
		
			
				
					| 
						
						
						
							
								
							
						
					 | 
				
			
			 | 
			 | 
			
				@ -80,6 +120,22 @@ public class SdiContainer implements SdiContainerInterface {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        }
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    }
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    /**
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				     * returns all registered services that implement or extend the given class
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				     *
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				     * @param clz parent class or interface
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				     * @return the list with instances, or an empty list if nothing is found
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				     */
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    @SuppressWarnings("WeakerAccess")
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    public <T> List<T> getInstancesThatImplement(Class<T> clz) {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        LOG.trace("instances of interface {} ordered", clz);
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        return definitions.stream()
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				            .filter(d -> clz.isAssignableFrom(d.getClz()))
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				            .map(ServiceDefinition::getClz)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				            .map(c -> clz.cast(getInstance(c)))
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				            .collect(Collectors.toList());
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    }
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    private <T> void handleSingleton(ServiceDefinition definition, T instance) {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        if (definition.isSingleton()) {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				            singletons.put(definition, instance);
 | 
			
		
		
	
	
		
			
				
					| 
						
							
								
							
						
						
						
					 | 
				
			
			 | 
			 | 
			
				
 
 |