Binding builder usability enhancements

Exposing base binding builder methods in specialized binding builders

Change-Id: I0fd51d0a30a9a86e0c13e2652bed07bbeb74e306
diff --git a/baku-toolkit/lib/build.gradle b/baku-toolkit/lib/build.gradle
index 63603f6..44eb03f 100644
--- a/baku-toolkit/lib/build.gradle
+++ b/baku-toolkit/lib/build.gradle
@@ -11,7 +11,7 @@
 import org.gradle.language.base.internal.compile.Compiler
 // You should change this after releasing a new version of the Baku Toolkit. See the
 // list of published versions at https://repo1.maven.org/maven2/io/v/baku-toolkit.
-version = '0.9.0'
+version = '0.10.0'
 group = 'io.v'
 
 def siteUrl = 'https://github.com/vanadium/java'
diff --git a/baku-toolkit/lib/src/main/java/io/v/baku/toolkit/BakuActivity.java b/baku-toolkit/lib/src/main/java/io/v/baku/toolkit/BakuActivity.java
index 47030b0..1222c08 100644
--- a/baku-toolkit/lib/src/main/java/io/v/baku/toolkit/BakuActivity.java
+++ b/baku-toolkit/lib/src/main/java/io/v/baku/toolkit/BakuActivity.java
@@ -8,6 +8,7 @@
 import android.os.Bundle;
 import android.os.PersistableBundle;
 
+import io.v.baku.toolkit.bind.BindingBuilder;
 import lombok.experimental.Delegate;
 import lombok.extern.slf4j.Slf4j;
 
@@ -26,7 +27,7 @@
  *
  *         // Example binding between "myDataRow" in Syncbase and myTextView in my_activity_layout.
  *         {@link #binder() binder}().{@link
- *             io.v.baku.toolkit.bind.BindingBuilder#onKey(java.lang.String)
+ *             BindingBuilder#onKey(java.lang.String)
  *             onKey}("myDataRow")
  *                 .{@link io.v.baku.toolkit.bind.ScalarBindingBuilder#bindTo(int)
  *                 bindTo}(R.id.myTextView);
diff --git a/baku-toolkit/lib/src/main/java/io/v/baku/toolkit/BakuAppCompatActivity.java b/baku-toolkit/lib/src/main/java/io/v/baku/toolkit/BakuAppCompatActivity.java
index cc3df89..6fdc64a 100644
--- a/baku-toolkit/lib/src/main/java/io/v/baku/toolkit/BakuAppCompatActivity.java
+++ b/baku-toolkit/lib/src/main/java/io/v/baku/toolkit/BakuAppCompatActivity.java
@@ -8,6 +8,7 @@
 import android.os.PersistableBundle;
 import android.support.v7.app.AppCompatActivity;
 
+import io.v.baku.toolkit.bind.BindingBuilder;
 import lombok.experimental.Delegate;
 import lombok.extern.slf4j.Slf4j;
 
@@ -26,7 +27,7 @@
  *
  *         // Example binding between "myDataRow" in Syncbase and myTextView in my_activity_layout.
  *         {@link #binder() binder}().{@link
- *             io.v.baku.toolkit.bind.BindingBuilder#onKey(java.lang.String)
+ *             BindingBuilder#onKey(java.lang.String)
  *             onKey}("myDataRow")
  *                 .{@link io.v.baku.toolkit.bind.ScalarBindingBuilder#bindTo(int)
  *                 bindTo}(R.id.myTextView);
diff --git a/baku-toolkit/lib/src/main/java/io/v/baku/toolkit/bind/BindingBuilder.java b/baku-toolkit/lib/src/main/java/io/v/baku/toolkit/bind/BindingBuilder.java
index 72e2c21..5a7e7c5 100644
--- a/baku-toolkit/lib/src/main/java/io/v/baku/toolkit/bind/BindingBuilder.java
+++ b/baku-toolkit/lib/src/main/java/io/v/baku/toolkit/bind/BindingBuilder.java
@@ -19,7 +19,8 @@
 import rx.subscriptions.CompositeSubscription;
 
 /**
- * Builder class for bindings from Syncbase data to UI elements.
+ * Starting builder class for bindings from Syncbase data to UI elements. To build concrete
+ * bindings, this builder must be specialized for a specific form of data binding.
  *
  * Three forms of data binding are currently available:
  *
@@ -31,7 +32,7 @@
  *   method. This is a {@linkplain CollectionBindingBuilder collection binding}.
  */
 @RequiredArgsConstructor
-public class BindingBuilder {
+public class BindingBuilder implements CommonBindingConfiguration<BindingBuilder> {
     protected Activity mActivity;
     protected RxTable mRxTable;
     protected CompositeSubscription mSubscriptionParent;
@@ -40,34 +41,30 @@
 
     private Context mViewAdapterContext;
 
+    @Override
     public BindingBuilder viewAdapterContext(final Context context) {
         mViewAdapterContext = context;
         return this;
     }
 
+    @Override
     public Context getDefaultViewAdapterContext() {
         return mViewAdapterContext == null ? mActivity : mViewAdapterContext;
     }
 
-
+    @Override
     public BindingBuilder activity(final Activity activity) {
         mActivity = activity;
         return this;
     }
 
+    @Override
     public BindingBuilder rxTable(final RxTable rxTable) {
         mRxTable = rxTable;
         return this;
     }
 
-    /**
-     * Sets the following properties from the given {@link BakuActivityTrait}:
-     *
-     * * {@link #activity(Activity)}
-     * * {@link #rxTable(RxTable)}
-     * * {@link #subscriptionParent(CompositeSubscription)}
-     * * {@link #onError(Action1)}
-     */
+    @Override
     public BindingBuilder activity(final BakuActivityTrait<?> trait) {
         return activity(trait.getVAndroidContextTrait().getAndroidContext())
                 .rxTable(trait.getSyncbaseTable())
@@ -75,17 +72,13 @@
                 .onError(trait::onSyncError);
     }
 
-    /**
-     * Sets the following properties from the given {@link VAndroidContextTrait}:
-     *
-     * * {@link #activity(Activity)}
-     * * {@link #onError(Action1)}
-     */
+    @Override
     public BindingBuilder activity(final VAndroidContextTrait<? extends Activity> trait) {
         return activity(trait.getAndroidContext())
                 .onError(ErrorReporters.getDefaultSyncErrorReporter(trait));
     }
 
+    @Override
     public BindingBuilder subscriptionParent(final CompositeSubscription subscriptionParent) {
         mSubscriptionParent = subscriptionParent;
         return this;
@@ -100,17 +93,17 @@
         return subscription;
     }
 
-    /**
-     * @return the current subscription parent.
-     */
+    @Override
     public CompositeSubscription getAllBindings() {
         return mSubscriptionParent;
     }
 
+    @Override
     public Subscription getLastBinding() {
         return mLastSubscription;
     }
 
+    @Override
     public BindingBuilder onError(final Action1<Throwable> onError) {
         mOnError = onError;
         return this;
diff --git a/baku-toolkit/lib/src/main/java/io/v/baku/toolkit/bind/CollectionBindingBuilder.java b/baku-toolkit/lib/src/main/java/io/v/baku/toolkit/bind/CollectionBindingBuilder.java
index 324ae71..740083e 100644
--- a/baku-toolkit/lib/src/main/java/io/v/baku/toolkit/bind/CollectionBindingBuilder.java
+++ b/baku-toolkit/lib/src/main/java/io/v/baku/toolkit/bind/CollectionBindingBuilder.java
@@ -21,7 +21,7 @@
  * {@linkplain BakuActivityTrait#getSyncbaseTable() direct database writes}.
  */
 public abstract class CollectionBindingBuilder<B extends CollectionBindingBuilder<B, T, A>,
-        T, A extends RangeAdapter> extends DerivedBuilder<B, BindingBuilder>{
+        T, A extends RangeAdapter> extends DerivedBindingBuilder<B, BindingBuilder> {
     public CollectionBindingBuilder(final BindingBuilder base) {
         super(base);
     }
diff --git a/baku-toolkit/lib/src/main/java/io/v/baku/toolkit/bind/CommonBindingConfiguration.java b/baku-toolkit/lib/src/main/java/io/v/baku/toolkit/bind/CommonBindingConfiguration.java
new file mode 100644
index 0000000..f361fd9
--- /dev/null
+++ b/baku-toolkit/lib/src/main/java/io/v/baku/toolkit/bind/CommonBindingConfiguration.java
@@ -0,0 +1,72 @@
+// Copyright 2015 The Vanadium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package io.v.baku.toolkit.bind;
+
+
+import android.app.Activity;
+import android.content.Context;
+
+import io.v.baku.toolkit.BakuActivityTrait;
+import io.v.baku.toolkit.VAndroidContextTrait;
+import io.v.rx.syncbase.RxTable;
+import rx.Subscription;
+import rx.functions.Action1;
+import rx.subscriptions.CompositeSubscription;
+
+/**
+ * Specifies the configuration common to all data binding builders.
+ */
+public interface CommonBindingConfiguration<T extends CommonBindingConfiguration<T>> {
+    // Non-chainable methods:
+
+    Context getDefaultViewAdapterContext();
+
+    /**
+     * @return the current subscription parent.
+     */
+    CompositeSubscription getAllBindings();
+
+    Subscription getLastBinding();
+
+    // Chainable methods:
+
+    T viewAdapterContext(final Context context);
+
+    T rxTable(final RxTable rxTable);
+
+    T activity(final Activity activity);
+
+    /**
+     * Configures this builder for a given {@link BakuActivityTrait}. The following properties are
+     * derived:
+     *
+     * * {@link #activity(Activity)}
+     * * {@link #rxTable(RxTable)}
+     * * {@link #subscriptionParent(CompositeSubscription)}
+     * * {@link #onError(Action1)}
+     */
+    T activity(final BakuActivityTrait<?> trait);
+
+    /**
+     * Configures this builder for a given {@link VAndroidContextTrait}. The following properties
+     * are derived:
+     *
+     * * {@link #activity(Activity)}
+     * * {@link #onError(Action1)}
+     */
+    T activity(final VAndroidContextTrait<? extends Activity> trait);
+
+    /**
+     * Sets the {@link CompositeSubscription} that will determine the lifespan of data bindings
+     * created by this builder. When that subscription is unsubscribed, the associated bindings will
+     * be terminated.
+     */
+    T subscriptionParent(final CompositeSubscription subscriptionParent);
+
+    /**
+     * Sets the error handler for bindings created by this builder.
+     */
+    T onError(final Action1<Throwable> onError);
+}
diff --git a/baku-toolkit/lib/src/main/java/io/v/baku/toolkit/bind/DerivedBindingBuilder.java b/baku-toolkit/lib/src/main/java/io/v/baku/toolkit/bind/DerivedBindingBuilder.java
new file mode 100644
index 0000000..28cc3c3
--- /dev/null
+++ b/baku-toolkit/lib/src/main/java/io/v/baku/toolkit/bind/DerivedBindingBuilder.java
@@ -0,0 +1,75 @@
+// Copyright 2016 The Vanadium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package io.v.baku.toolkit.bind;
+
+import android.app.Activity;
+import android.content.Context;
+
+import io.v.baku.toolkit.BakuActivityTrait;
+import io.v.baku.toolkit.VAndroidContextTrait;
+import io.v.rx.syncbase.RxTable;
+import lombok.RequiredArgsConstructor;
+import lombok.experimental.Delegate;
+import rx.Subscription;
+import rx.functions.Action1;
+import rx.subscriptions.CompositeSubscription;
+
+@RequiredArgsConstructor
+public class DerivedBindingBuilder<T extends DerivedBindingBuilder<T, B>,
+        B extends CommonBindingConfiguration<B>>
+        extends ExtensibleBuilder<T>
+        implements CommonBindingConfiguration<T> {
+
+    private interface NonChainable {
+        Context getDefaultViewAdapterContext();
+        CompositeSubscription getAllBindings();
+        Subscription getLastBinding();
+    }
+
+    @Delegate(types = NonChainable.class)
+    protected final B mBase;
+
+    @Override
+    public T viewAdapterContext(final Context context) {
+        mBase.viewAdapterContext(context);
+        return mSelf;
+    }
+
+    @Override
+    public T activity(final Activity activity) {
+        mBase.activity(activity);
+        return mSelf;
+    }
+
+    @Override
+    public T rxTable(final RxTable rxTable) {
+        mBase.rxTable(rxTable);
+        return mSelf;
+    }
+
+    @Override
+    public T activity(final BakuActivityTrait<?> trait) {
+        mBase.activity(trait);
+        return mSelf;
+    }
+
+    @Override
+    public T activity(final VAndroidContextTrait<? extends Activity> trait) {
+        mBase.activity(trait);
+        return mSelf;
+    }
+
+    @Override
+    public T subscriptionParent(final CompositeSubscription subscriptionParent) {
+        mBase.subscriptionParent(subscriptionParent);
+        return mSelf;
+    }
+
+    @Override
+    public T onError(final Action1<Throwable> onError) {
+        mBase.onError(onError);
+        return mSelf;
+    }
+}
diff --git a/baku-toolkit/lib/src/main/java/io/v/baku/toolkit/bind/DerivedBuilder.java b/baku-toolkit/lib/src/main/java/io/v/baku/toolkit/bind/DerivedBuilder.java
deleted file mode 100644
index db9dce9..0000000
--- a/baku-toolkit/lib/src/main/java/io/v/baku/toolkit/bind/DerivedBuilder.java
+++ /dev/null
@@ -1,12 +0,0 @@
-// Copyright 2016 The Vanadium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package io.v.baku.toolkit.bind;
-
-import lombok.RequiredArgsConstructor;
-
-@RequiredArgsConstructor
-public class DerivedBuilder<T extends DerivedBuilder<T, B>, B> extends ExtensibleBuilder<T> {
-    protected final B mBase;
-}
diff --git a/baku-toolkit/lib/src/main/java/io/v/baku/toolkit/bind/IdListBindingBuilder.java b/baku-toolkit/lib/src/main/java/io/v/baku/toolkit/bind/IdListBindingBuilder.java
index 1a2f07b..46b1b7e 100644
--- a/baku-toolkit/lib/src/main/java/io/v/baku/toolkit/bind/IdListBindingBuilder.java
+++ b/baku-toolkit/lib/src/main/java/io/v/baku/toolkit/bind/IdListBindingBuilder.java
@@ -22,7 +22,7 @@
  * or [1, 3, 4], whereas {@linkplain PrefixBindingBuilder prefix bindings} would resolve to either
  * [1, 2, 3, 4] or [1, 3, 2, 4].
  *
- * @see io.v.baku.toolkit.bind.BindingBuilder#onIdList(String)
+ * @see BindingBuilder#onIdList(String)
  */
 public class IdListBindingBuilder<A extends RangeAdapter>
         extends CollectionBindingBuilder<IdListBindingBuilder<A>, String, A> {
diff --git a/baku-toolkit/lib/src/main/java/io/v/baku/toolkit/bind/PrefixBindingBuilder.java b/baku-toolkit/lib/src/main/java/io/v/baku/toolkit/bind/PrefixBindingBuilder.java
index 54f5fa1..2452cca 100644
--- a/baku-toolkit/lib/src/main/java/io/v/baku/toolkit/bind/PrefixBindingBuilder.java
+++ b/baku-toolkit/lib/src/main/java/io/v/baku/toolkit/bind/PrefixBindingBuilder.java
@@ -25,8 +25,8 @@
  * If {@code T} is {@link Comparable}, the default row ordering is natural ordering on row values.
  * Otherwise, the default is natural ordering on row names.
  *
- * @see io.v.baku.toolkit.bind.BindingBuilder#onPrefix(String)
- * @see io.v.baku.toolkit.bind.BindingBuilder#onPrefix(PrefixRange)
+ * @see BindingBuilder#onPrefix(String)
+ * @see BindingBuilder#onPrefix(PrefixRange)
  */
 public class PrefixBindingBuilder<T, A extends RangeAdapter>
         extends CollectionBindingBuilder<PrefixBindingBuilder<T, A>, RxTable.Row<T>, A> {
diff --git a/baku-toolkit/lib/src/main/java/io/v/baku/toolkit/bind/ScalarBindingBuilder.java b/baku-toolkit/lib/src/main/java/io/v/baku/toolkit/bind/ScalarBindingBuilder.java
index f7c6125..043221b 100644
--- a/baku-toolkit/lib/src/main/java/io/v/baku/toolkit/bind/ScalarBindingBuilder.java
+++ b/baku-toolkit/lib/src/main/java/io/v/baku/toolkit/bind/ScalarBindingBuilder.java
@@ -36,7 +36,7 @@
  * type checking here is acceptable.
  */
 public class ScalarBindingBuilder<T>
-        extends DerivedBuilder<ScalarBindingBuilder<T>, BindingBuilder> {
+        extends DerivedBindingBuilder<ScalarBindingBuilder<T>, BindingBuilder> {
     private String mKey;
     private boolean mExplicitDefaultValue;
     private T mDeleteValue, mDefaultValue;