// Copyright 2015 The Project Buendia Authors // // 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 distrib- // uted 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 // specific language governing permissions and limitations under the License. package org.projectbuendia.client.events; import java.util.HashSet; import java.util.Set; import de.greenrobot.event.EventBus; /** An {@link EventBus} wrapper to be used by asynchronous CRUD operations on the data model. */ public final class DefaultCrudEventBus implements CrudEventBus { private final Object mSubscribersLock = new Object(); private final EventBus mWrapped; private final Set<Object> mSubscribers; private CleanupSubscriber mCleanupSubscriber; @Override public void register(Object subscriber) { if (subscriber instanceof CleanupSubscriber) { throw new IllegalArgumentException( "CleanupSubscribers must be registered with registerCleanupSubscriber()."); } mWrapped.register(subscriber); synchronized (mSubscribersLock) { mSubscribers.add(subscriber); } } @Override public void unregister(Object subscriber) { if (subscriber instanceof CleanupSubscriber) { throw new IllegalArgumentException( "CleanupSubscribers must be unregistered with unregisterCleanupSubscriber()."); } mWrapped.unregister(subscriber); synchronized (mSubscribersLock) { if (mSubscribers.remove(subscriber) && mCleanupSubscriber != null && mSubscribers.size() == 0) { mCleanupSubscriber.onAllUnregistered(); } } } @Override public void post(Object event) { mWrapped.post(event); } @Override public void registerCleanupSubscriber(CleanupSubscriber subscriber) { synchronized (mSubscribersLock) { if (mCleanupSubscriber != null) { mWrapped.unregister(subscriber); } mCleanupSubscriber = subscriber; mWrapped.register(mCleanupSubscriber); } } @Override public void unregisterCleanupSubscriber(CleanupSubscriber subscriber) { // The registered CleanupSubscriber may call this method; however, Java synchronized blocks // are reentrant so synchronizing again is okay. synchronized (mSubscribersLock) { if (mCleanupSubscriber != subscriber) { throw new IllegalStateException( "A CleanupSubscriber must be registered with registerCleanupSubscriber() " + "before it can be unregistered."); } mWrapped.unregister(subscriber); mCleanupSubscriber = null; } } /** Creates a new {@link DefaultCrudEventBus} that wraps the specified {@link EventBus}. */ DefaultCrudEventBus(EventBus wrapped) { mWrapped = wrapped; mSubscribers = new HashSet<>(); } }