DefaultTypeMappingContext implements TypeMappingContext { @Override public void register(Class<?> repositoryType, Class<?> implementation) { if (Modifier.isAbstract(implementation.getModifiers()) || Modifier.isInterface(implementation.getModifiers())) { log.error("Cannot bind a non-concrete class as an implementation for a non-concrete class"); throw new RepositoryDefinitionException(repositoryType, "Cannot bind a non-concrete class as an implementation for a " + "non-concrete class"); } log.info("Registering implementation " + implementation + " to super type " + repositoryType + "; this means any repository of this type will inherit functionality defined in the " + "bound implementation class."); mappings.putIfAbsent(repositoryType, new LinkedList<>()); mappings.get(repositoryType).add(implementation); } DefaultTypeMappingContext();  DefaultTypeMappingContext(boolean registerDefaults);  DefaultTypeMappingContext(TypeMappingContext parent); @Override void register(Class<?> repositoryType, Class<?> implementation); @Override List<Class<?>> getImplementations(Class<?> repositoryType); @Override List<TypeMapping<?>> getMappings(Class<?> repositoryType);  }
@Test(expectedExceptions = RepositoryDefinitionException.class) public void testRegisteringAbstractImplementation() { final DefaultTypeMappingContext context = new DefaultTypeMappingContext(); context.register(Object.class, AbstractImplementation.class); }
@Test(expectedExceptions = RepositoryDefinitionException.class) public void testRegisteringInterfaceImplementation() { final DefaultTypeMappingContext context = new DefaultTypeMappingContext(); context.register(Object.class, InterfaceImplementation.class); }