<commit_before>package brooklyn.entity.proxying;

import static com.google.common.base.Preconditions.checkNotNull;

import java.lang.reflect.Modifier;
import java.util.Arrays;
import java.util.Deque;
import java.util.LinkedList;
import java.util.Set;

import brooklyn.entity.Entity;
import brooklyn.util.exceptions.Exceptions;
import brooklyn.util.javalang.Reflections;

import com.google.common.collect.BiMap;
import com.google.common.collect.HashBiMap;
import com.google.common.collect.Sets;

public class BasicEntityTypeRegistry implements EntityTypeRegistry {

    private final BiMap<Class<?>, Class<?>> registry = HashBiMap.create();
    private final BiMap<Class<?>, Class<?>> cache = HashBiMap.create();
    
    private final Object mutex = new Object();
    
    @Override
    public <T extends Entity> EntityTypeRegistry registerImplementation(Class<T> type, Class<? extends T> implClazz) {
        checkNotNull(type, "type");
        checkNotNull(implClazz, "implClazz");
        checkIsImplementation(type, implClazz);
        checkIsNewStyleImplementation(implClazz);

        synchronized (mutex) {
            Class<?> existingType = registry.inverse().get(implClazz);
            if (existingType != null && !type.equals(existingType)) {
                throw new IllegalArgumentException("Implementation "+implClazz+" already registered against type "+existingType+"; cannot also register against "+type);
            }
            
            registry.put(type, implClazz);
            cache.forcePut(type, implClazz);
        }
        
        return this;
    }
    
    @Override
    public <T extends Entity> Class<? extends T> getImplementedBy(Class<T> type) {
        synchronized (mutex) {
            Class<?> result = cache.get(type);
            if (result != null) {
                return (Class<? extends T>) result;
            }
            result = getFromAnnotation(type);
            if (result == null) {
                if (!type.isInterface() && ((type.getModifiers() & Modifier.ABSTRACT)==0)) {
                    // warning delivered later, in InternalEntityFactory
                    result = type;
                } else {
                    throw new IllegalArgumentException("Interface "+type+" is not annotated with @"+ImplementedBy.class.getSimpleName()+", and no implementation is registered");
                }
            }
            cache.put(type, result);
            return (Class<? extends T>) result;
        }<commit_msg>BasicEntityTypeRegistry: improve logging<commit_after>package brooklyn.entity.proxying;

import static com.google.common.base.Preconditions.checkNotNull;

import java.lang.reflect.Modifier;
import java.util.Arrays;
import java.util.Deque;
import java.util.LinkedList;
import java.util.Set;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import brooklyn.entity.Entity;
import brooklyn.entity.basic.AbstractEntity;
import brooklyn.util.exceptions.Exceptions;
import brooklyn.util.javalang.Reflections;

import com.google.common.collect.BiMap;
import com.google.common.collect.HashBiMap;
import com.google.common.collect.Sets;

public class BasicEntityTypeRegistry implements EntityTypeRegistry {

    private static final Logger LOG = LoggerFactory.getLogger(BasicEntityTypeRegistry.class);

    private final BiMap<Class<?>, Class<?>> registry = HashBiMap.create();
    private final BiMap<Class<?>, Class<?>> cache = HashBiMap.create();
    
    private final Object mutex = new Object();
    
    @Override
    public <T extends Entity> EntityTypeRegistry registerImplementation(Class<T> type, Class<? extends T> implClazz) {
        checkNotNull(type, "type");
        checkNotNull(implClazz, "implClazz");
        checkIsImplementation(type, implClazz);
        checkIsNewStyleImplementation(implClazz);

        synchronized (mutex) {
            Class<?> existingType = registry.inverse().get(implClazz);
            if (existingType != null && !type.equals(existingType)) {
                throw new IllegalArgumentException("Implementation "+implClazz+" already registered against type "+existingType+"; cannot also register against "+type);
            }
            
            LOG.debug("Implementation {} registered against type {}", implClazz, type);
            registry.put(type, implClazz);
            cache.forcePut(type, implClazz);
        }
        
        return this;
    }
    
    @Override
    public <T extends Entity> Class<? extends T> getImplementedBy(Class<T> type) {
        synchronized (mutex) {
            Class<?> result = cache.get(type);
            if (result != null) {
                if (LOG.isTraceEnabled()) LOG.trace("Implementation {} returned for type {}", result, type);
                return (Class<? extends T>) result;
            }
            result = getFromAnnotation(type);
            if (result == null) {
                if (!type.isInterface() && ((type.getModifiers() & Modifier.ABSTRACT)==0)) {
                    // warning delivered later, in InternalEntityFactory
                    result = type;
                } else {
                    throw new IllegalArgumentException("Interface "+type+" is not annotated with @"+ImplementedBy.class.getSimpleName()+", and no implementation is registered");
                }
            }
            if (LOG.isTraceEnabled()) LOG.trace("Implementation {} returned for type {}", result, type);
            cache.put(type, result);
            return (Class<? extends T>) result;
        }
{'fraction_non_alphanumeric': 0.11143428467551354, 'fraction_numerical': 0.0007271405199054717, 'mean_word_length': 2.7175675675675675, 'pattern_counts': {'":': 0, '<': 35, '<?xml version=': 0, '>': 35, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5147452', 'n_tokens_mistral': 1444, 'n_tokens_neox': 1431, 'n_words': 356}