com.eviware.loadui.impl.addon.AddonRegistryImpl.java Source code

Java tutorial

Introduction

Here is the source code for com.eviware.loadui.impl.addon.AddonRegistryImpl.java

Source

/*
 * Copyright 2013 SmartBear Software
 * 
 * Licensed under the EUPL, Version 1.1 or - as soon they will be approved by the European Commission - subsequent
 * versions of the EUPL (the "Licence");
 * You may not use this work except in compliance with the Licence.
 * You may obtain a copy of the Licence at:
 * 
 * http://ec.europa.eu/idabc/eupl
 * 
 * Unless required by applicable law or agreed to in writing, software distributed under the Licence is
 * distributed on an "AS IS" basis, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
 * express or implied. See the Licence for the specific language governing permissions and limitations
 * under the Licence.
 */
package com.eviware.loadui.impl.addon;

import java.util.Collections;
import java.util.Hashtable;
import java.util.Map;
import java.util.Set;
import java.util.WeakHashMap;

import org.osgi.framework.BundleContext;
import org.osgi.framework.ServiceRegistration;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.osgi.context.BundleContextAware;

import com.eviware.loadui.api.addon.Addon;
import com.eviware.loadui.api.addon.AddonHolder;
import com.eviware.loadui.api.addon.AddonRegistry;
import com.google.common.base.Predicate;
import com.google.common.collect.HashMultimap;
import com.google.common.collect.Iterables;
import com.google.common.collect.Maps;
import com.google.common.collect.Multimap;

public class AddonRegistryImpl implements AddonRegistry, BundleContextAware {
    public static final Logger log = LoggerFactory.getLogger(AddonRegistryImpl.class);

    private static void loadAddon(AddonHolder addonHolder, Addon.Factory<?> factory) {
        addonHolder.getAddon(factory.getType());
    }

    //TODO: We can't use generics here until the OSGi jars stop using compilation flags that are not compatible with Java7.
    private final Map<String, ServiceRegistration/* <?> */> registrations = Maps.newHashMap();
    private final Map<String, Addon.Factory<?>> factories = Maps.newHashMap();
    private final Multimap<Class<?>, Addon.Factory<?>> eagerAddons = HashMultimap.create();
    private final Set<AddonHolder> registeredHolders = Collections
            .newSetFromMap(new WeakHashMap<AddonHolder, Boolean>());

    private BundleContext bundleContext;

    @Override
    public synchronized void setBundleContext(BundleContext bundleContext) {
        this.bundleContext = bundleContext;
    }

    @Override
    public synchronized <T extends Addon> void registerFactory(Class<T> type, Addon.Factory<T> factory) {
        Hashtable<String, String> properties = new Hashtable<>();
        properties.put("type", type.getName());

        registrations.put(type.getName(), bundleContext.registerService(Addon.Factory.class, factory, properties));
    }

    @Override
    public synchronized <T extends Addon> void unregisterFactory(Class<T> type, Addon.Factory<T> factory) {
        ServiceRegistration/* <?> */ registration = registrations.get(type.getName());
        if (registration != null)
            registration.unregister();
    }

    @SuppressWarnings("unchecked")
    @Override
    public synchronized <T extends Addon> Addon.Factory<T> getFactory(Class<T> type) {
        return (Addon.Factory<T>) factories.get(type.getName());
    }

    /**
     * Called by Spring whenever a new Factory is registered as an OSGi service.
     * 
     * @param factory
     * @param properties
     */
    public synchronized void factoryAdded(final Addon.Factory<?> factory, Map<String, String> properties) {
        final String typeStr = factory.getType().getName();

        factories.put(typeStr, factory);
        for (Class<?> type : factory.getEagerTypes()) {
            eagerAddons.put(type, factory);
        }
        log.debug("Registered Addon.Factory for type: {}", typeStr);

        Iterable<AddonHolder> matchingHolders = Iterables.filter(registeredHolders, new Predicate<AddonHolder>() {
            @Override
            public boolean apply(final AddonHolder addonHolder) {
                return Iterables.all(factory.getEagerTypes(), new Predicate<Class<?>>() {
                    @Override
                    public boolean apply(Class<?> cls) {
                        return cls.isInstance(addonHolder);
                    }
                });
            }
        });

        for (AddonHolder holder : matchingHolders) {
            loadAddon(holder, factory);
        }
    }

    /**
     * Called by Spring whenever a Factory is unregistered as an OSGi service.
     * 
     * @param factory
     * @param properties
     */
    public synchronized void factoryRemoved(Addon.Factory<?> factory, Map<String, String> properties) {
        final String typeStr = factory.getType().getName();
        if (factories.remove(typeStr) != null) {
            for (Class<?> type : factory.getEagerTypes()) {
                eagerAddons.remove(type, factory);
            }
            log.debug("Unregistered Addon.Factory for type: {}", typeStr);
        }
    }

    @Override
    public synchronized void registerAddonHolder(final AddonHolder addonHolder) {
        registeredHolders.add(addonHolder);
        final Predicate<Class<?>> typeMatcher = new Predicate<Class<?>>() {
            @Override
            public boolean apply(Class<?> input) {
                return input.isInstance(addonHolder);
            }
        };

        for (Addon.Factory<?> factory : Iterables
                .concat(Maps.filterKeys(eagerAddons.asMap(), typeMatcher).values())) {
            loadAddon(addonHolder, factory);
        }
    }

    @Override
    public void unregisterAddonHolder(AddonHolder addonHolder) {
        registeredHolders.remove(addonHolder);
    }
}