/* * Copyright (C) 2015 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.jboss.errai.ioc.client.lifecycle.impl; import java.util.ArrayList; import java.util.Collection; import java.util.HashMap; import java.util.IdentityHashMap; import java.util.Iterator; import java.util.Map; import java.util.Map.Entry; import javax.inject.Singleton; import org.jboss.errai.ioc.client.container.Factory; import org.jboss.errai.ioc.client.lifecycle.api.AuditableLifecycleListener; import org.jboss.errai.ioc.client.lifecycle.api.LifecycleEvent; import org.jboss.errai.ioc.client.lifecycle.api.LifecycleListener; import org.jboss.errai.ioc.client.lifecycle.api.LifecycleListenerGenerator; import org.jboss.errai.ioc.client.lifecycle.api.LifecycleListenerRegistrar; @Singleton public class LifecycleListenerRegistrarImpl implements LifecycleListenerRegistrar { private final Map<Object, Collection<? extends AuditableLifecycleListener<?>>> activeListenerMap = new IdentityHashMap<Object, Collection<? extends AuditableLifecycleListener<?>>>(); private final Map<Class<?>, Collection<LifecycleListenerGenerator<?>>> generatorMap = new HashMap<Class<?>, Collection<LifecycleListenerGenerator<?>>>(); @Override public <T> Iterable<LifecycleListener<T>> getListeners(final Class<? extends LifecycleEvent<T>> eventType, final T instance) { final Collection<AuditableLifecycleListener<T>> allInstanceListeners = getInstanceListeners(instance); final Collection<LifecycleListener<T>> eventListeners = new ArrayList<LifecycleListener<T>>(); for (final LifecycleListener<T> listener : allInstanceListeners) { if (listener.isObserveableEventType(eventType)) { eventListeners.add(listener); } } return eventListeners; } private <T> Collection<AuditableLifecycleListener<T>> getInstanceListeners(T instance) { instance = Factory.maybeUnwrapProxy(instance); @SuppressWarnings("unchecked") Collection<AuditableLifecycleListener<T>> listeners = (Collection<AuditableLifecycleListener<T>>) activeListenerMap .get(instance); if (listeners == null) { listeners = generateNewLifecycleListeners(instance); activeListenerMap.put(instance, listeners); } return listeners; } protected <T> Collection<AuditableLifecycleListener<T>> generateNewLifecycleListeners(T instance) { instance = Factory.maybeUnwrapProxy(instance); final Collection<AuditableLifecycleListener<T>> newListeners = new ArrayList<AuditableLifecycleListener<T>>(); final Collection<LifecycleListenerGenerator<?>> generators = generatorMap.get(instance.getClass()); if (generators != null) { for (final LifecycleListenerGenerator<?> generator : generators) { @SuppressWarnings("unchecked") final LifecycleListener<T> listener = (LifecycleListener<T>) generator.newInstance(); newListeners.add(new AuditableLifecycleListener<T>() { @Override public void observeEvent(final LifecycleEvent<T> event) { listener.observeEvent(event); } @Override public boolean isObserveableEventType(Class<? extends LifecycleEvent<T>> eventType) { return listener.isObserveableEventType(eventType); } @SuppressWarnings("unchecked") @Override public LifecycleListenerGenerator<T> getGenerator() { return (LifecycleListenerGenerator<T>) generator; } @Override public LifecycleListener<T> unwrap() { return listener; } }); } } return newListeners; } @Override public <T> void registerGenerator(Class<T> lifecycleType, LifecycleListenerGenerator<T> generator) { Collection<LifecycleListenerGenerator<?>> generators = generatorMap.get(lifecycleType); if (generators == null) { generators = new ArrayList<LifecycleListenerGenerator<?>>(); generatorMap.put(lifecycleType, generators); } if (!generators.contains(generator)) generators.add(generator); } @Override public <T> void unregisterGenerator(final Class<T> lifecycleType, final LifecycleListenerGenerator<T> generator) { unregisterGenerators(lifecycleType, generator); unregisterActiveListeners(lifecycleType, generator); } private <T> void unregisterActiveListeners(final Class<T> lifecycleType, final LifecycleListenerGenerator<T> generator) { for (final Entry<Object, Collection<? extends AuditableLifecycleListener<?>>> entry : activeListenerMap.entrySet()) { if (entry.getKey().getClass().equals(lifecycleType)) { @SuppressWarnings("unchecked") final Iterator<AuditableLifecycleListener<T>> iterator = (Iterator<AuditableLifecycleListener<T>>) entry .getValue().iterator(); AuditableLifecycleListener<T> listener; while (iterator.hasNext()) { listener = iterator.next(); if (listener.getGenerator() == generator) iterator.remove(); } } } } private <T> void unregisterGenerators(final Class<T> lifecycleType, final LifecycleListenerGenerator<T> generator) { final Collection<LifecycleListenerGenerator<?>> listenerGenerators = generatorMap.get(lifecycleType); if (listenerGenerators != null) listenerGenerators.remove(generator); } @Override public <T> boolean endInstanceLifecycle(final T instance) { return activeListenerMap.remove(Factory.maybeUnwrapProxy(instance)) != null; } @Override public <T> void registerListener(T instance, final LifecycleListener<T> listener) { instance = Factory.maybeUnwrapProxy(instance); @SuppressWarnings("unchecked") Collection<AuditableLifecycleListener<T>> activeListeners = (Collection<AuditableLifecycleListener<T>>) activeListenerMap .get(instance); if (activeListeners == null) { activeListeners = generateNewLifecycleListeners(instance); activeListenerMap.put(instance, activeListeners); } activeListeners.add(new AuditableLifecycleListener<T>() { @Override public void observeEvent(LifecycleEvent<T> event) { listener.observeEvent(event); } @Override public boolean isObserveableEventType(Class<? extends LifecycleEvent<T>> eventType) { return listener.isObserveableEventType(eventType); } @Override public LifecycleListenerGenerator<T> getGenerator() { // Return a dummy generator to avoid needing logic elsewhere to check // for NPEs. return new LifecycleListenerGenerator<T>() { @Override public LifecycleListener<T> newInstance() { // This method should never be called. return null; } }; } @Override public LifecycleListener<T> unwrap() { return listener; } }); } @Override public <T> void unregisterListener(T instance, final LifecycleListener<T> listener) { instance = Factory.maybeUnwrapProxy(instance); @SuppressWarnings("unchecked") final Collection<AuditableLifecycleListener<T>> instanceListeners = (Collection<AuditableLifecycleListener<T>>) activeListenerMap .get(instance); if (instanceListeners != null) { final Iterator<AuditableLifecycleListener<T>> iterator = instanceListeners.iterator(); while (iterator.hasNext()) if (iterator.next().unwrap() == listener) { iterator.remove(); break; } } } }