All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.ioc.commons.impl.android.flowcontrol.operationmanager.AndroidOperationManagerImpl Maven / Gradle / Ivy

package org.ioc.commons.impl.android.flowcontrol.operationmanager;

import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.ioc.commons.flowcontrol.common.BindRegistration;
import org.ioc.commons.flowcontrol.operationmanager.IsOperation;
import org.ioc.commons.flowcontrol.operationmanager.OperationHandler;
import org.ioc.commons.flowcontrol.operationmanager.OperationManager;
import org.ioc.commons.utils.Format;
import org.ioc.commons.utils.FormatterLogger;

import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.Bundle;
import android.util.Log;

public class AndroidOperationManagerImpl> implements OperationManager {

	private static final FormatterLogger logger = FormatterLogger.getLogger(AndroidOperationManagerImpl.class);

	private static final String OPERATION_BEGINNING_INTENT_ACTION = "org.ioc.commons.impl.android.flowcontrol.operationmanager.OPERATION.BEGINNING";
	private static final String OPERATION_FINISHING_INTENT_ACTION = "org.ioc.commons.impl.android.flowcontrol.operationmanager.OPERATION.FINISHING";

	private static final String OPERATION_KEY = "OPERATION";
	private final static String SUCCESS_KEY = "SUCCESS";

	private class AndroidOperationManagerBindRegistration implements BindRegistration {

		private final Context context;
		private final AndroidOperationManagerImpl.OperationStore beginningOs;
		private final AndroidOperationManagerImpl.OperationStore finishingOs;

		public AndroidOperationManagerBindRegistration(Context context,
				AndroidOperationManagerImpl.OperationStore beginningOs,
				AndroidOperationManagerImpl.OperationStore finishingOs) {
			this.context = context;
			this.beginningOs = beginningOs;
			this.finishingOs = finishingOs;
		}

		@Override
		public void unbind() {

			stored.remove(this.beginningOs);
			stored.remove(this.finishingOs);

			this.context.unregisterReceiver(this.beginningOs.receiver);
			this.context.unregisterReceiver(this.finishingOs.receiver);
		}

	}

	private static class OperationReceiver> extends BroadcastReceiver {

		private final OperationHandler handler;
		private final Map, BindRegistration> onceHandlers;
		private final List onGoingOps;
		private final boolean finishing;

		public OperationReceiver(boolean finishing, OperationHandler handler,
				Map, BindRegistration> onceHandlers) {
			this(finishing, handler, onceHandlers, null);
		}

		public OperationReceiver(boolean finishing, OperationHandler handler,
				Map, BindRegistration> onceHandlers, List onGoingOps) {

			this.onGoingOps = onGoingOps;
			this.finishing = finishing;
			this.handler = handler;
			this.onceHandlers = onceHandlers;
		}

		@Override
		public void onReceive(Context context, Intent intent) {

			if (!onceHandlers.isEmpty()) {
				BindRegistration registration = onceHandlers.remove(handler);
				if (registration != null) {
					registration.unbind();
				}
			}

			@SuppressWarnings("unchecked")
			O operation = (O) intent.getSerializableExtra(OPERATION_KEY);

			if (!finishing) {
				if (onGoingOps == null || onGoingOps.size() == 1) {
					handler.onOperationBeginning(context, operation);
				}
			} else {
				if (onGoingOps == null || onGoingOps.isEmpty()) {
					handler.onOperationFinished(context, operation, intent.getBooleanExtra(SUCCESS_KEY, false));
				}
			}
		}
	}

	private class OperationStore {
		IntentFilter filter;
		OperationReceiver receiver;
		O operation;

		@Override
		public String toString() {
			return "OperationStore [filter=" + filter + ", receiver=" + receiver + ", operation=" + operation + "]";
		}

	}

	private final Set stored = new HashSet<>();

	private final Context context;
	private final Map, BindRegistration> onceHandlers = new HashMap, BindRegistration>();
	private final List onGoingOps = new ArrayList();
	private boolean active;

	public AndroidOperationManagerImpl(Context context, boolean initiallyActive) {
		this.context = context;
		this.active = initiallyActive;
	}

	@Override
	public BindRegistration bindOperation(O operation, OperationHandler handler) {
		IntentFilter beginningFilter = new IntentFilter(OPERATION_BEGINNING_INTENT_ACTION);
		IntentFilter finishingFilter = new IntentFilter(OPERATION_FINISHING_INTENT_ACTION);

		OperationReceiver beginningReceiver = new OperationReceiver(false, handler, onceHandlers);

		OperationReceiver finishingReceiver = new OperationReceiver(true, handler, onceHandlers);

		AndroidOperationManagerImpl.OperationStore beginningOs = addOperationReceiver(beginningFilter,
				beginningReceiver, operation);
		AndroidOperationManagerImpl.OperationStore finishingOs = addOperationReceiver(finishingFilter,
				finishingReceiver, operation);

		return new AndroidOperationManagerBindRegistration(context, beginningOs, finishingOs);
	}

	private OperationStore addOperationReceiver(IntentFilter filter, OperationReceiver receiver, O operation) {
		OperationStore os = new OperationStore();

		os.filter = filter;
		os.receiver = receiver;
		os.operation = operation;

		stored.add(os);

		if (active) {
			context.registerReceiver(receiver, filter);
		}

		return os;
	}

	@Override
	public BindRegistration bindOperationOnce(O operation, OperationHandler handler) {
		BindRegistration registration = bindOperation(operation, handler);

		this.onceHandlers.put(handler, registration);

		return registration;
	}

	@Override
	public BindRegistration bindOperationsRunning(OperationHandler handler) {
		IntentFilter beginningFilter = new IntentFilter(OPERATION_BEGINNING_INTENT_ACTION);
		IntentFilter finishingFilter = new IntentFilter(OPERATION_FINISHING_INTENT_ACTION);

		OperationReceiver beginningReceiver = new OperationReceiver(false, handler, onceHandlers, onGoingOps);

		OperationReceiver finishingReceiver = new OperationReceiver(true, handler, onceHandlers, onGoingOps);

		AndroidOperationManagerImpl.OperationStore beginningOs = addOperationReceiver(beginningFilter,
				beginningReceiver, null);
		AndroidOperationManagerImpl.OperationStore finishingOs = addOperationReceiver(finishingFilter,
				finishingReceiver, null);

		return new AndroidOperationManagerBindRegistration(context, beginningOs, finishingOs);
	}

	@Override
	public void operationBeginning(O operation) {
		Log.v(this.getClass().getSimpleName(), "Beginning " + operation);
		this.onGoingOps.add(operation);
		Intent intent = new Intent(OPERATION_BEGINNING_INTENT_ACTION);
		intent.putExtra(OPERATION_KEY, operation);
		context.sendBroadcast(intent);
	}

	@Override
	public boolean operationFinished(O operation, boolean success) {
		Log.v(this.getClass().getSimpleName(),
				Format.substitute("Finishing {0}. Success? {1}. Pending ops? {2}", operation, success,
						this.getPendingOpCount()));
		boolean removed = this.onGoingOps.remove(operation);
		Intent intent = new Intent(OPERATION_FINISHING_INTENT_ACTION);
		intent.putExtra(OPERATION_KEY, operation);
		intent.putExtra(SUCCESS_KEY, success);

		context.sendBroadcast(intent);

		Log.v(this.getClass().getSimpleName(),
				Format.substitute("Finished {0}. Removed? {1}. Pending ops? {2}", operation, removed,
						this.getPendingOpCount()));
		return removed;
	}

	@Override
	public int getPendingOpCount() {
		return onGoingOps.size();
	}

	@Override
	public boolean isBusy() {
		return (!this.onGoingOps.isEmpty());
	}

	@Override
	public boolean isOpPending(O operation) {
		return onGoingOps.contains(operation);
	}

	@Override
	public List getPendingOpList() {
		return Collections.unmodifiableList(onGoingOps);
	}

	public void onCreate() {
		/*
		 * Nothing to do
		 */
	}
	
	public void onStart() {
		for (AndroidOperationManagerImpl.OperationStore os : this.stored) {
			context.registerReceiver(os.receiver, os.filter);
		}
	}

	public void onResume() {
		this.active = true;
	}

	public void onPause() {
		this.active = false;
	}

	public void onStop() {
		for (AndroidOperationManagerImpl.OperationStore os : this.stored) {
			try {
				context.unregisterReceiver(os.receiver);
			} catch (Exception e) {
				logger.warn(e, "Failure during unregistering reciver. Ignoring it.");
			}
		}
	}

	public void onDestroy() {
		/*
		 * Nothing to do
		 */
	}

	public void onActivityCreated(Bundle savedInstanceState) {
		/*
		 * Nothing to do
		 */
	}

}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy