package com.dragome.forms.bindings.client.command; import static com.dragome.forms.bindings.client.condition.Conditions.isNot; import com.dragome.forms.bindings.client.interceptor.Interceptor; import com.dragome.forms.bindings.client.interceptor.InterceptorChain; import com.dragome.forms.bindings.client.interceptor.Invocation; import com.dragome.forms.bindings.client.value.DelegatingValueModel; import com.dragome.forms.bindings.client.value.ValueModel; import com.dragome.forms.bindings.extra.user.client.Command; /** * Base class for all UiCommands that defines the common state (enabled) and methods * for configuring it. */ public abstract class UiCommandSupport implements UiCommand { private DelegatingValueModel<Boolean> enabledModel= new DelegatingValueModel<Boolean>(true); protected InterceptorChain interceptorChain= new InterceptorChain(); public ValueModel<Boolean> enabled() { return enabledModel; } /** * Configures when this command should be enabled. Multiple calls to this method will replace * the existing value with the new one. * <p/> * This command will be referenced by the specified value model (think memory leak). So if the * specified model is long lived then you'll need to invoke enabledWhen(null) to clear the * reference. * * @param enabled a value model representing the enabled state of this command or null to remove * the enabledWhen condition. */ public void enableWhen(ValueModel<Boolean> enabled) { enabledModel.setDelegate(enabled); } /** * Configures when this command should be disabled. This method is equivalent to calling * {@link #enableWhen(com.pietschy.gwt.pectin.client.value.ValueModel) enableWhen(isNot(disabled))}. * <p/> * See {@link #enableWhen(com.pietschy.gwt.pectin.client.value.ValueModel)} for information on memory * leaks. * * @param disabled a value model representing the disabled state of this command. */ public void disableWhen(ValueModel<Boolean> disabled) { enableWhen(isNot(disabled)); } public final void interceptUsing(Interceptor interceptor) { interceptorChain.addInterceptor(interceptor); } /** * Allows subclasses to intercept the execution. This method will run before any * other interceptors. * <p/> * The command <b>will only execute</b> when <code>invocation.proceed()</code> or <code>invocation.getProceedCommand().execute()</code>. * is called. * <p/> * To cancel the command don't call <code>invocation.proceed()</code> or <code>invocation.getProceedCommand().execute()</code>. * <p/> * <b>NOTE:</b> Calling <code>super.beforeExecute(invocation)</code> is equivalent to simply calling * <code>invocation.proceed()</code>. * <p/> * Examples: * <pre> * protected void beforeExecute(Invocation invocation) * { * // only proceed if the model is valid. * if (model.validate()) * { * invocation.proceed(); * } * } * </pre> * * @param invocation the invocation chain. * @see #interceptUsing(com.pietschy.gwt.pectin.client.interceptor.Interceptor) */ protected void intercept(Invocation invocation) { invocation.proceed(); } protected final void runWithInterceptors(Command command) { // create the interceptor chain with our execution at the end of it. By passing it to // before starting we guarantee that beforeStarting has first shot and intercepting it. intercept(interceptorChain.buildInvocationChain(command)); } }