![JAR search and dependency download from the Maven repository](/logo.png)
com.sencha.gxt.data.shared.loader.Loader Maven / Gradle / Ivy
package com.sencha.gxt.data.shared.loader;
import com.google.gwt.core.client.Callback;
import com.google.gwt.core.client.GWT;
import com.google.gwt.event.shared.GwtEvent;
import com.google.gwt.event.shared.HandlerRegistration;
import com.google.gwt.event.shared.SimpleEventBus;
import com.sencha.gxt.core.shared.event.CancellableEvent;
import com.sencha.gxt.core.shared.event.GroupingHandlerRegistration;
import com.sencha.gxt.data.shared.loader.BeforeLoadEvent.BeforeLoadHandler;
import com.sencha.gxt.data.shared.loader.LoadExceptionEvent.LoadExceptionHandler;
import com.sencha.gxt.data.shared.loader.LoaderHandler.HasLoaderHandlers;
/**
* Abstract base class for objects that can load remote data.
*
*
* The optional input object passed with the load request is logically called a
* "load config" with the object returned by the loader called the
* "load result".
*
*
* Typically, loaders work with {@link DataProxy} and {@link DataReader} to help
* perform the load operations. The DataProxy
is responsible for
* obtaining the remote data. The DataReader
is responsible for
* "processing" the remote data and converting the data to the expected format.
*
*
* - Events:
* - {@link BeforeLoadEvent}
* - {@link LoadEvent}
* - {@link LoadExceptionEvent}
*
*
* @param the type of the data used to configure
* @param the type of data being returned by the loader
*/
public class Loader implements HasLoaderHandlers {
private static class WrapperProxy implements DataProxy {
private final DataProxy proxy;
private final DataReader reader;
public WrapperProxy(DataProxy proxy, DataReader reader) {
this.proxy = proxy;
this.reader = reader;
}
public void load(final C loadConfig, final Callback callback) {
proxy.load(loadConfig, new Callback() {
public void onSuccess(T result) {
if (GWT.isProdMode()) {
callback.onSuccess(reader.read(loadConfig, result));
} else {
try {
callback.onSuccess(reader.read(loadConfig, result));
} catch (ClassCastException ex) {
GWT.log("Improper cast in " + reader.getClass()
+ ", cannot convert the incoming data to the correct return type. "
+ "Please provide an implementation of createReturnData()", ex);
throw ex;
}
}
}
@Override
public void onFailure(Throwable caught) {
callback.onFailure(caught);
}
});
}
}
protected DataProxy proxy;
protected C lastConfig;
protected boolean reuseConfig;
private SimpleEventBus eventBus;
/**
* Creates a new base loader instance. Since a data reader is not used, the
* data returned by the data proxy will not be read and converted by a reader.
*
* @param proxy the data proxy
*/
public Loader(DataProxy proxy) {
this.proxy = proxy;
}
/**
* Creates a new loader with the given proxy and reader.
*
* @param proxy the data proxy
* @param reader the data reader
*/
public Loader(DataProxy proxy, DataReader reader) {
this(new WrapperProxy(proxy, reader));
}
public HandlerRegistration addBeforeLoadHandler(BeforeLoadHandler handler) {
return ensureHandler().addHandler(BeforeLoadEvent.getType(), handler);
}
@Override
public HandlerRegistration addLoaderHandler(LoaderHandler handler) {
GroupingHandlerRegistration group = new GroupingHandlerRegistration();
group.add(ensureHandler().addHandler(BeforeLoadEvent.getType(), handler));
group.add(ensureHandler().addHandler(LoadEvent.getType(), handler));
group.add(ensureHandler().addHandler(LoadExceptionEvent.getType(), handler));
return group;
}
public HandlerRegistration addLoadExceptionHandler(LoadExceptionHandler handler) {
return ensureHandler().addHandler(LoadExceptionEvent.getType(), handler);
}
public HandlerRegistration addLoadHandler(LoadHandler handler) {
return ensureHandler().addHandler(LoadEvent.getType(), handler);
}
/**
* Returns the last config.
*
* @return the last config
*/
public Object getLastConfig() {
return lastConfig;
}
/**
* Returns the loader's data proxy.
*
* @return the data proxy
*/
public DataProxy, ?> getProxy() {
return proxy;
}
/**
* Returns true if the load config is being reused.
*
* @return the reuse load config state
*/
public boolean isReuseLoadConfig() {
return reuseConfig;
}
/**
* Loads the data using the current configuration. Fires the
* {@link BeforeLoadEvent} before the request, then the
* {@link LoadEvent} after the load operation.
*
* @return true if the load was requested, false if cancelled
*/
public boolean load() {
C config = (reuseConfig && lastConfig != null) ? lastConfig : newLoadConfig();
config = prepareLoadConfig(config);
return load(config);
}
/**
* Loads the data using the given load configuration. Fires the
* {@link BeforeLoadEvent} before the request, then the
* {@link LoadEvent} after the load operation. The current load
* configuration object can be retrieved using {@link #getLastConfig()}.
*
* @param loadConfig the load config
* @return true if the load was requested, false if cancelled
*/
public boolean load(C loadConfig) {
if (fireEvent(new BeforeLoadEvent(loadConfig))) {
lastConfig = loadConfig;
loadData(loadConfig);
return true;
}
return false;
}
/**
* Sets whether the same load config instance should be used for load
* operations (defaults to false).
*
* @param reuseLoadConfig true to reuse
*/
public void setReuseLoadConfig(boolean reuseLoadConfig) {
this.reuseConfig = reuseLoadConfig;
}
protected boolean fireEvent(GwtEvent> event) {
ensureHandler().fireEvent(event);
if (event instanceof CancellableEvent) {
return !((CancellableEvent) event).isCancelled();
}
return true;
}
protected void loadData(final C config) {
Callback callback = new Callback() {
public void onFailure(Throwable caught) {
caught.printStackTrace();
onLoadFailure(config, caught);
}
public void onSuccess(M result) {
onLoadSuccess(config, result);
}
};
if (proxy == null) {
loadData(config, callback);
return;
}
proxy.load(config, callback);
}
/**
* Called by {@link #loadData(Object)} when a data proxy is not being used.
*
* @param config the load config
* @param callback the callback
*/
protected void loadData(C config, Callback callback) {
}
/**
* Template method to allow custom BaseLoader subclasses to provide their own
* implementation of LoadConfig
*/
protected C newLoadConfig() {
return null;
}
/**
* Called when a load operation fails.
*
* @param loadConfig the load config
* @param t the exception
*/
protected void onLoadFailure(C loadConfig, Throwable t) {
fireEvent(new LoadExceptionEvent(loadConfig, t));
}
/**
* Called when the remote data has been received.
*
* @param loadConfig the load config
* @param data data
*/
protected void onLoadSuccess(C loadConfig, M data) {
fireEvent(new LoadEvent(loadConfig, data));
}
/**
* Template method to allow custom subclasses to prepare the load config prior
* to loading data
*/
protected C prepareLoadConfig(C config) {
return config;
}
SimpleEventBus ensureHandler() {
return eventBus == null ? eventBus = new SimpleEventBus() : eventBus;
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy