package org.zkoss.zktest.test2;
import org.apache.commons.beanutils.BeanUtils;
import org.zkoss.bind.BindUtils;
import org.zkoss.bind.annotation.Command;
import org.zkoss.zk.ui.Desktop;
import org.zkoss.zk.ui.Executions;
import org.zkoss.zk.ui.event.Event;
import org.zkoss.zk.ui.event.EventListener;
import org.zkoss.zk.ui.event.EventQueue;
import org.zkoss.zk.ui.event.EventQueues;
import org.zkoss.zk.ui.util.Clients;
public class B65_ZK_1840_ViewModel {
private String sequenceStatus;
private String backgroundStatus;
private String manualStatus;
@Command("startSequencedOperation")
public void onStartSequencedOperation() {
launchSequencedOperation();
}
@Command("startBackgroundOperations")
public void onStartBackgroundOperations() {
launchBackgroundOperations();
}
@Command("startManualOperation")
public void onStartManualOperation() {
launchManualOperation();
}
@Command("startAllOperations")
public void onStartLongOperation() {
launchAllOperations();
}
private void launchAllOperations() {
launchSequencedOperation();
launchBackgroundOperations();
launchManualOperation();
}
private void launchBackgroundOperations() {
backgroundStatus = "";
appendStatus("backgroundStatus", "BackgroundOperation ---> ");
LongOperation backgroundOperation1 = backgroundOperation("backgroundQueue1", "backgroundStatus", 3000);
LongOperation backgroundOperation2 = backgroundOperation("backgroundQueue2", "backgroundStatus", 5000);
backgroundOperation1.start();
backgroundOperation2.start();
}
private void launchSequencedOperation() {
sequenceStatus = "";
appendStatus("sequenceStatus", "SequencedOperation ---> ");
LongOperation sequenceOperation = sequenceOperationChain();
sequenceOperation.start();
}
private void launchManualOperation() {
manualStatus = "";
appendStatus("manualStatus", "ManualOperation ---> ");
final Desktop desktop = Executions.getCurrent().getDesktop();
desktop.enableServerPush(true);
Thread manualOperation = manualOperation(desktop);
manualOperation.start();
}
private LongOperation sequenceOperationChain() {
//1. Operation
BusyLongOperation firstOperation = busyOperation("loadQueue", "loading from DB", "sequenceStatus", 2000);
//2. Operation
BusyLongOperation secondOperation = busyOperation("processQueue", "processing in backend", "sequenceStatus", 2000);
firstOperation.setNextOperation(secondOperation);
return firstOperation;
}
private BusyLongOperation busyOperation(final String queueName, String busyMessage,
final String statusField, final int duration) {
return new BusyLongOperation(queueName, busyMessage) {
protected void onStart() {
super.onStart();
appendStatus(statusField, queueName + " started ... ");
}
protected void execute() {
sleep(duration);
}
protected void onFinish() {
appendStatus(statusField, "done. ");
super.onFinish();
};
};
}
private LongOperation backgroundOperation(final String queueName, final String statusField, final int duration) {
return new LongOperation(queueName) {
protected void onStart() {
appendStatus(statusField, queueName + " started ... ");
}
protected void execute() {
sleep(duration);
}
protected void onFinish() {
appendStatus(statusField, queueName + " finished. ");
}
};
}
private Thread manualOperation(final Desktop desktop) {
return new Thread() {
public void run() {
try {
Executions.activate(desktop);
appendStatus("manualStatus", "manual operation started ... ");
Executions.deactivate(desktop);
Thread.sleep(1000);
Executions.activate(desktop);
appendStatus("manualStatus", " 1 ");
Executions.deactivate(desktop);
Thread.sleep(1000);
Executions.activate(desktop);
appendStatus("manualStatus", " 2 ");
Executions.deactivate(desktop);
Thread.sleep(1000);
Executions.activate(desktop);
appendStatus("manualStatus", " 3 ");
Executions.deactivate(desktop);
Thread.sleep(1000);
Executions.activate(desktop);
appendStatus("manualStatus", "done");
Executions.deactivate(desktop);
} catch (InterruptedException e) {
e.printStackTrace();
}
desktop.enableServerPush(false);
}
};
}
private void appendStatus(String statusField, String newStatus) {
System.out.println(statusField + newStatus);
try {
String currentStatus = BeanUtils.getProperty(this, statusField);
BeanUtils.setProperty(this, statusField, currentStatus + newStatus);
} catch (Exception e) {
e.printStackTrace();
}
BindUtils.postNotifyChange(null, null, this, statusField);
}
public String getSequenceStatus() {
return sequenceStatus;
}
public void setSequenceStatus(String sequenceStatus) {
this.sequenceStatus = sequenceStatus;
}
public String getBackgroundStatus() {
return backgroundStatus;
}
public void setBackgroundStatus(String backgroundStatus) {
this.backgroundStatus = backgroundStatus;
}
public String getManualStatus() {
return manualStatus;
}
public void setManualStatus(String manualStatus) {
this.manualStatus = manualStatus;
}
// helper classes
public static abstract class BusyLongOperation extends LongOperation {
private String busyMessage;
private LongOperation nextOperation;
public void setNextOperation(LongOperation nextOperation) {
this.nextOperation = nextOperation;
}
public BusyLongOperation(String queueName, String busyMessage) {
super(queueName);
this.busyMessage = busyMessage;
}
protected void onStart() {
Clients.showBusy(busyMessage);
}
protected void onFinish() {
Clients.clearBusy();
if(nextOperation != null) {
nextOperation.start();
}
}
}
public static abstract class LongOperation {
private String queueName;
public LongOperation(String queueName) {
super();
this.queueName = queueName;
}
abstract protected void onStart();
abstract protected void execute();
abstract protected void onFinish();
public void start() {
if (EventQueues.exists(queueName)) {
Clients.showNotification("Queue with name '" + queueName + "' is already running. Try later.");
return;
}
final EventQueue<Event> eventQueue = EventQueues.lookup(queueName, true);
final EventListener<Event> executionListener = new EventListener<Event>() {
public void onEvent(Event event) throws Exception {
System.out.println("Execution Started " + queueName);
execute();
System.out.println("Execution Finished " + queueName);
}
};
final EventListener<Event> callbackListener = new EventListener<Event>() {
public void onEvent(Event event) throws Exception {
eventQueue.unsubscribe(executionListener); //problem here
EventQueues.remove(queueName); //or problem here
onFinish();
}
};
onStart();
eventQueue.subscribe(executionListener, callbackListener);
eventQueue.publish(new Event("launch dummy"));
}
}
private void sleep(int milliseconds) {
try {
Thread.sleep(milliseconds);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}