package org.ovirt.engine.ui.frontend.communication;
import java.util.ArrayList;
import java.util.List;
import org.ovirt.engine.core.common.queries.VdcQueryParametersBase;
import com.google.gwt.event.shared.EventBus;
import com.google.inject.Inject;
/**
* This class is a singleton and manages how {@code VdcOperation}s are added to the queue to be processed.
*/
public class VdcOperationManager {
/**
* Event bus to propagate events related to operation processing.
*/
private final EventBus eventBus;
/**
* The operation queue. It can hold any kind of VdcOperation.
*/
private final List<VdcOperation<?, ?>> operationQueue = new ArrayList<>();
/**
* The operation processor.
*/
private final OperationProcessor processor;
/**
* Constructor.
* @param operationProcessor the operation processor.
*/
@Inject
public VdcOperationManager(final EventBus eventBus, final OperationProcessor operationProcessor) {
this.eventBus = eventBus;
this.processor = operationProcessor;
}
/**
* Add operation to the queue.
* @param operation The {@code VdcOperation} to add.
* @return {@code true} if the user was allowed to add the operation, {@code false} otherwise
*/
public boolean addOperation(final VdcOperation<?, ?> operation) {
return addOperationImpl(operation);
}
/**
* Add operation to the queue. Fire event when operation is successfully added if fireEvent is true.
* If the operation determined by equals is already in the queue, do not add it again.
* @param operation The {@code VdcOperation} to add.
* @return {@code true} if the user was allowed to add the operation, {@code false} otherwise
*/
private boolean addOperationImpl(final VdcOperation<?, ?> operation) {
// If the operation is not already in the queue || the operation is an action (allows duplicates).
// Then add this operation to the queue, and process the queue immediately.
final boolean operationCanBeAdded = !operationQueue.contains(operation) || operation.allowDuplicates();
if (operationCanBeAdded && operationQueue.add(operation)) {
processor.processOperation(this);
if (engineSessionRefreshed(operation)) {
EngineSessionRefreshedEvent.fire(eventBus);
}
}
return true;
}
/**
* Add a list of operations to the queue. Once all the operations are added, fire an event that something
* is in the queue.
* @param operationList The list of {@code VdcOperation}
* @return {@code true} if the user was allowed to add the operation, {@code false} otherwise
*/
public boolean addOperationList(final List<VdcOperation<?, ?>> operationList) {
boolean allowed = true;
for (VdcOperation<?, ?> operation: operationList) {
if (!addOperationImpl(operation)) {
allowed = false;
}
}
// Call the processor.
processor.processOperation(this);
return allowed;
}
/**
* Pull the head of the queue and return the operation.
* @return The head of the queue, or null if empty.
*/
public VdcOperation<?, ?> pollOperation() {
return !operationQueue.isEmpty() ? operationQueue.remove(0) : null;
}
/**
* Log out the user.
* @param callback The callback to call when the operation is completed.
*/
public void logoutUser(final UserCallback<?> callback) {
processor.logoutUser(callback);
}
/**
* Store a value on the back-end in the session.
* @param key The key.
* @param value The value.
*/
public void storeInHttpSession(final String key, final String value) {
processor.storeInHttpSession(key, value);
}
/**
* Retrieve a stored value from the back-end session.
* @param key The key.
* @param callback The callback to call with the value.
*/
public void retrieveFromHttpSession(final String key, final StorageCallback callback) {
processor.retrieveFromHttpSession(key, callback);
}
/**
* Returns {@code true} if execution of given operation caused the Engine session to be refreshed.
*/
boolean engineSessionRefreshed(VdcOperation<?, ?> operation) {
// Actions always refresh the Engine session
if (operation.isAction()) {
return true;
}
// Queries optionally refresh the Engine session
else if (((VdcQueryParametersBase) operation.getParameter()).getRefresh()) {
return true;
}
return false;
}
}