blob: f6f7837e503730d3e6418ea436874e6fc9a0c9b5 [file] [log] [blame]
/*
* Copyright 2012 Thomas Broyer <t.broyer@ltgt.net>
*
* 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.apache.hupa.client.mapper;
import com.google.gwt.activity.shared.Activity;
import com.google.gwt.core.client.GWT;
import com.google.gwt.core.client.RunAsyncCallback;
import com.google.gwt.event.shared.EventBus;
import com.google.gwt.user.client.ui.AcceptsOneWidget;
/**
* Makes it easy to put any {@link Activity} behind a split-point.
* <p>
* For simple activities, that could be done using an
* {@link com.google.gwt.user.client.AsyncProxy AsyncProxy}, but it's not
* possible for activities created through factories or via dependency
* injection.
* <p>
* As a bonus, the {@link Activity} won't be instantiated at all in case the
* {@link ActivityAsyncProxy} is {@link #onCancel cancelled} before the
* {@link GWT.runAsync async call} returns.
*/
public abstract class ActivityAsyncProxy implements Activity {
private boolean hasAsyncBeenIssued;
private boolean hasAsyncBeenCancelled;
private boolean hasAsyncFailed;
private AcceptsOneWidget display;
private EventBus eventBus;
private Activity instance;
@Override
public String mayStop() {
checkHasAsyncFailed();
assert this.instance != null;
return this.instance.mayStop();
}
@Override
public void onCancel() {
if (this.instance != null) {
this.instance.onCancel();
}
checkHasAsyncFailed();
this.hasAsyncBeenCancelled = true;
}
@Override
public void onStop() {
checkHasAsyncFailed();
assert this.instance != null;
this.instance.onStop();
}
@Override
public void start(AcceptsOneWidget panel, EventBus eventBus) {
if (this.instance != null) {
this.instance.start(panel, eventBus);
return;
}
checkHasAsyncFailed();
assert !this.hasAsyncBeenIssued || this.hasAsyncBeenCancelled;
this.display = panel;
this.eventBus = eventBus;
this.hasAsyncBeenCancelled = false;
if (!this.hasAsyncBeenIssued) {
this.hasAsyncBeenIssued = true;
if (!ActivityAsyncProxy.this.hasAsyncBeenCancelled) {
assert ActivityAsyncProxy.this.instance == null;
ActivityAsyncProxy.this.instance = createInstance();
ActivityAsyncProxy.this.instance.start(
ActivityAsyncProxy.this.display,
ActivityAsyncProxy.this.eventBus);
}
// doAsync(new RunAsyncCallback() {
//
// @Override
// public void onSuccess() {
// if (!ActivityAsyncProxy.this.hasAsyncBeenCancelled) {
// assert ActivityAsyncProxy.this.instance == null;
// ActivityAsyncProxy.this.instance = createInstance();
// ActivityAsyncProxy.this.instance.start(
// ActivityAsyncProxy.this.display,
// ActivityAsyncProxy.this.eventBus);
// }
// }
//
// @Override
// public void onFailure(Throwable reason) {
// ActivityAsyncProxy.this.hasAsyncFailed = true;
// if (GWT.getUncaughtExceptionHandler() != null) {
// GWT.getUncaughtExceptionHandler().onUncaughtException(
// reason);
// }
// }
// });
}
}
/**
* Implementors should simply call {@link GWT#runAsync} here, and nothing
* else.
* <p>
* This is required to have a different split-point generated for each
* {@link ActivityAsyncProxy} sub-class.
*/
protected abstract void doAsync(RunAsyncCallback callback);
protected abstract Activity createInstance();
private void checkHasAsyncFailed() {
if (this.hasAsyncFailed) {
throw new IllegalStateException("runAsync load previously failed");
}
}
}