Response to API usability study 2016.02.23

Documenting the 'key' setter in SyncbaseBinding.Builder, making two-way
bindings the default even for TextView, adding a few convenience
overloads, and starting to improve docs.

Change-Id: I114ef085f5a16d194c4ed1c6dae5c61ab0fb080a
diff --git a/baku-toolkit/lib/build.gradle b/baku-toolkit/lib/build.gradle
index ef83ece..24f751f 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.7.1'
+version = '0.8.0'
 group = 'io.v'
 
 def siteUrl = 'https://github.com/vanadium/java'
diff --git a/baku-toolkit/lib/src/main/java/io/v/baku/toolkit/bind/DebouncingCoordinator.java b/baku-toolkit/lib/src/main/java/io/v/baku/toolkit/bind/DebouncingCoordinator.java
index f612b9b..6e67a41 100644
--- a/baku-toolkit/lib/src/main/java/io/v/baku/toolkit/bind/DebouncingCoordinator.java
+++ b/baku-toolkit/lib/src/main/java/io/v/baku/toolkit/bind/DebouncingCoordinator.java
@@ -22,16 +22,16 @@
  * {@value #DEFAULT_IO_DEBOUNCE_MILLIS} ms) after the latest write, then taking the latest read.
  * Write/watch latency can cause reflexive watch changes from Syncbase to arrive after subsequent
  * changes to the UI state have already been made, causing a stuttering revert.
- * <p>
+ *
  * A simple debounce on the uplink or downlink doesn't solve the problem because it effectively just
  * adds a delay to the boundary condition. To prevent this, any update from the model must be
  * throttled if there was a recent update from the view.
- * <p>
+ *
  * Unfortunately for rapid concurrent updates this can result in divergence which should be handled
  * via conflict resolution or CRDT.
- * <p>
+ *
  * This coordinator is included in the default coordinator chain for
- * {@linkplain io.v.baku.toolkit.bind.SyncbaseBinding.Builder#bindTwoWay(TextView) two-way
+ * {@linkplain io.v.baku.toolkit.bind.SyncbaseBinding.Builder#bindTo(TextView) two-way
  * <code>TextView</code> bindings}.
  */
 @RequiredArgsConstructor
diff --git a/baku-toolkit/lib/src/main/java/io/v/baku/toolkit/bind/SuppressWriteOnReadCoordinator.java b/baku-toolkit/lib/src/main/java/io/v/baku/toolkit/bind/SuppressWriteOnReadCoordinator.java
index 8741ee4..d93d352 100644
--- a/baku-toolkit/lib/src/main/java/io/v/baku/toolkit/bind/SuppressWriteOnReadCoordinator.java
+++ b/baku-toolkit/lib/src/main/java/io/v/baku/toolkit/bind/SuppressWriteOnReadCoordinator.java
@@ -16,11 +16,11 @@
  * Android {@link android.widget.EditText} fires text update events whether changes originate from
  * the user or from code. If we don't suppress writes while responding to Syncbase changes with
  * Android widgets, we easily end up in update loops.
- * <p>
+ *
  * To operate correctly, this coordinator must occur single-threaded with the widget binding layer.
- * <p>
+ *
  * This coordinator is required (and injected if missing) in the coordinator chain for
- * {@linkplain io.v.baku.toolkit.bind.SyncbaseBinding.Builder#bindTwoWay(TextView) two-way
+ * {@linkplain io.v.baku.toolkit.bind.SyncbaseBinding.Builder#bindTo(TextView) two-way
  * <code>TextView</code> bindings}.
  */
 @RequiredArgsConstructor
diff --git a/baku-toolkit/lib/src/main/java/io/v/baku/toolkit/bind/SyncbaseBinding.java b/baku-toolkit/lib/src/main/java/io/v/baku/toolkit/bind/SyncbaseBinding.java
index 80c2a46..526ec6c 100644
--- a/baku-toolkit/lib/src/main/java/io/v/baku/toolkit/bind/SyncbaseBinding.java
+++ b/baku-toolkit/lib/src/main/java/io/v/baku/toolkit/bind/SyncbaseBinding.java
@@ -40,6 +40,9 @@
         private T mDeleteValue, mDefaultValue;
         private final List<CoordinatorChain<T>> mCoordinators = new ArrayList<>();
 
+        /**
+         * Sets the row name for the Syncbase side of the binding.
+         */
         public Builder<T> key(final String key) {
             mKey = key;
             return this;
@@ -112,14 +115,14 @@
         }
 
         /**
-         * Constructs a read-only binding from a `String` in Syncbase to the text of a
-         * {@link TextView}. This is a simple unidirectional binding that does not involve any
-         * coordinators.
+         * Constructs a binding from a `String` in Syncbase to the text of a {@link TextView}, only
+         * propagating changes from Syncbase to the `TextView` and not in the other direction. This
+         * is a simple unidirectional binding that does not involve any coordinators.
          *
          * If {@link #subscriptionParent(CompositeSubscription) subscriptionParent} is set, this
          * method adds the generated binding to it.
          */
-        public Builder<T> bindOneWay(final TextView textView) {
+        public Builder<T> bindReadOnly(final TextView textView) {
             @SuppressWarnings("unchecked")
             final Builder<String> t = (Builder<String>) this;
 
@@ -134,6 +137,27 @@
         }
 
         /**
+         * Binds to the provided view in a read-only direction. This method delegates to
+         * {@link #bindReadOnly(TextView)} for {@link TextView}s. Other view types are not yet
+         * supported.
+         */
+        public Builder<T> bindReadOnly(final View view) {
+            if (view instanceof TextView) {
+                return bindReadOnly((TextView) view);
+            } else {
+                throw new IllegalArgumentException("No read-only binding for view " + view);
+            }
+        }
+
+        /**
+         * Binds to the view identified by {@code viewId} in a read-only direction.
+         * @see #bindTo(View)
+         */
+        public Builder<T> bindReadOnly(final @IdRes int viewId) {
+            return bindReadOnly(mActivity.findViewById(viewId));
+        }
+
+        /**
          * Constructs a two-way, bidirectional binding between a `String` in Syncbase and the text
          * of a {@link TextView}.
          *
@@ -152,7 +176,7 @@
          * method adds the generated binding to it.
          * @todo(rosswang): produce a SyncbaseBinding, and allow mutable bindings.
          */
-        public Builder<T> bindTwoWay(final TextView textView) {
+        public Builder<T> bindTo(final TextView textView) {
             @SuppressWarnings("unchecked")
             final Builder<String> t = (Builder<String>) this;
 
@@ -178,22 +202,6 @@
         }
 
         /**
-         * Calls {@link #bindTwoWay(TextView)} if the {@link TextView} is an {@link EditText},
-         * {@link #bindOneWay(TextView)} otherwise.
-         */
-        public Builder<T> bindTo(final TextView textView) {
-            return textView instanceof EditText ? bindTwoWay(textView) : bindOneWay(textView);
-        }
-
-        /**
-         * An alias for {@link #bindTwoWay(TextView)}, which is the default for {@link EditText}
-         * widgets.
-         */
-        public Builder<T> bindTo(final EditText editText) {
-            return bindTwoWay(editText);
-        }
-
-        /**
          * Binds to the provided view in a default manner. This method delegates to
          * {@link #bindTo(TextView)} for {@link TextView}s. Other view types are not yet supported.
          */
diff --git a/baku-toolkit/lib/src/main/java/io/v/baku/toolkit/package-info.java b/baku-toolkit/lib/src/main/java/io/v/baku/toolkit/package-info.java
index 0205082..1d86382 100644
--- a/baku-toolkit/lib/src/main/java/io/v/baku/toolkit/package-info.java
+++ b/baku-toolkit/lib/src/main/java/io/v/baku/toolkit/package-info.java
@@ -9,20 +9,20 @@
  * {@link io.v.baku.toolkit.BakuActivityMixin} for custom inheritance trees). Then, for any UI
  * widget that should have distributed state, the client application should build data bindings by
  * chaining methods from a {@link io.v.baku.toolkit.BakuActivityTrait#binder() binder()} call,
- * binding shared data fields to UI widget properties. For <a href="https://goo.gl/P0Ag9a"
- * target="_blank">example</a>, the following binds a data key named `"text"` to the text of a
- * {@link android.widget.TextView} with ID `textView`:
+ * binding shared data fields in the Syncbase distributed storage system to UI widget properties.
+ * For [example](https://goo.gl/P0Ag9a), the following binds a data key named `"text"` to the text
+ * of a {@link android.widget.TextView} with ID `textView`:
  *
  * ```java
  * {@literal @}Override
  * protected void onCreate(final Bundle savedInstanceState) {
  *     super.onCreate(savedInstanceState);
- *     setContentView(R.layout.activity_layout);
+ *     setContentView(R.layout.my_activity_layout);
  *
  *     {@link io.v.baku.toolkit.BakuActivityMixin#binder() binder}().{@link
- *         io.v.baku.toolkit.bind.SyncbaseBinding.Builder#key(java.lang.String) key}("text")
+ *         io.v.baku.toolkit.bind.SyncbaseBinding.Builder#key(java.lang.String) key}("myDataRow")
  *             .{@link io.v.baku.toolkit.bind.SyncbaseBinding.Builder#bindTo(int)
- *             bindTo}(R.id.textView);
+ *             bindTo}(R.id.myTextView);
  *     }
  * }
  * ```