Baku - incrementally adding docs

Change-Id: Icfc925572535fc41d0f0d2a7cedd05da002aa7b0
diff --git a/baku-toolkit/gradle/wrapper/gradle-wrapper.properties b/baku-toolkit/gradle/wrapper/gradle-wrapper.properties
index 89af0bd..b39d8fb 100644
--- a/baku-toolkit/gradle/wrapper/gradle-wrapper.properties
+++ b/baku-toolkit/gradle/wrapper/gradle-wrapper.properties
@@ -3,4 +3,4 @@
 distributionPath=wrapper/dists
 zipStoreBase=GRADLE_USER_HOME
 zipStorePath=wrapper/dists
-distributionUrl=https\://services.gradle.org/distributions/gradle-2.9-all.zip
+distributionUrl=https\://services.gradle.org/distributions/gradle-2.11-all.zip
diff --git a/baku-toolkit/lib/build.gradle b/baku-toolkit/lib/build.gradle
index fafc703..1a6d960 100644
--- a/baku-toolkit/lib/build.gradle
+++ b/baku-toolkit/lib/build.gradle
@@ -1,3 +1,8 @@
+import org.gradle.api.tasks.javadoc.internal.JavadocSpec
+import org.gradle.jvm.internal.toolchain.JavaToolChainInternal
+import org.gradle.jvm.platform.JavaPlatform
+import org.gradle.jvm.platform.internal.DefaultJavaPlatform
+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.0'
@@ -129,16 +134,98 @@
     classifier = 'sources'
 }
 
-task javadoc (type: Javadoc) {
+task javadoc (type: FullProcessingJavadoc) {
     source = android.sourceSets.main.java.srcDirs
     classpath += project.files(android.getBootClasspath().join(File.pathSeparator))
 
+    options.overview = 'src/main/java/overview.html'
+
     if (JavaVersion.current().isJava8Compatible()) {
         // TODO(rosswang): Can we get rid of this?
         options.addStringOption('Xdoclint:none', '-quiet')
     }
 }
 
+/**
+ * https://groups.google.com/d/topic/gradle-dev/R83dy_6PHMc/discussion
+ */
+@ParallelizableTask
+class FullProcessingJavadoc extends Javadoc {
+    private Set<File> sourceDirs
+
+    @Override
+    public void setSource(Object sourceDirs) {
+        this.sourceDirs = sourceDirs
+        super.setSource(sourceDirs)
+    }
+
+    @Override
+    protected void generate() {
+        final File destinationDir = getDestinationDir();
+
+        if (options.getDestinationDirectory() == null) {
+            options.destinationDirectory(destinationDir);
+        }
+
+        options.classpath(new ArrayList<File>(getClasspath().getFiles()));
+
+        if (!GUtil.isTrue(options.getWindowTitle()) && GUtil.isTrue(getTitle())) {
+            options.windowTitle(getTitle());
+        }
+        if (options instanceof StandardJavadocDocletOptions) {
+            StandardJavadocDocletOptions docletOptions = (StandardJavadocDocletOptions) options;
+            if (!GUtil.isTrue(docletOptions.getDocTitle()) && GUtil.isTrue(getTitle())) {
+                docletOptions.setDocTitle(getTitle());
+            }
+        }
+
+        if (maxMemory != null) {
+            final List<String> jFlags = options.getJFlags();
+            final Iterator<String> jFlagsIt = jFlags.iterator();
+            boolean containsXmx = false;
+            while (!containsXmx && jFlagsIt.hasNext()) {
+                final String jFlag = jFlagsIt.next();
+                if (jFlag.startsWith("-Xmx")) {
+                    containsXmx = true;
+                }
+            }
+            if (!containsXmx) {
+                options.jFlags("-Xmx" + maxMemory);
+            }
+        }
+
+        Set<String> roots = new HashSet<>();
+        for (File sourceDir : sourceDirs) {
+            roots += sourceDir.absolutePath
+        }
+        /*Set<String> packages = new HashSet<>();
+        for (File sourceFile : getSource()) {
+            println sourceFile.getPath()
+        }*/
+        options.setSourceNames(Arrays.asList('io.v'));
+        options.addStringOption('subpackages', 'io.v')
+        options.addStringsOption('sourcepath').value = new ArrayList<>(roots)
+
+        executeExternalJavadoc();
+    }
+
+    private void executeExternalJavadoc() {
+        JavadocSpec spec = new JavadocSpec();
+        spec.setExecutable(executable);
+        spec.setOptions(options);
+        spec.setIgnoreFailures(!failOnError);
+        spec.setWorkingDir(getProject().getProjectDir());
+        spec.setOptionsFile(getOptionsFile());
+
+        Compiler<JavadocSpec> generator = ((JavaToolChainInternal) getToolChain()).select(getPlatform()).newCompiler(JavadocSpec.class);
+        generator.execute(spec);
+    }
+
+    private static JavaPlatform getPlatform() {
+        return DefaultJavaPlatform.current();
+    }
+}
+
 task javadocJar(type: Jar, dependsOn: javadoc) {
     from tasks.javadoc
     classifier = 'javadoc'
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 3e424ea..0277502 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
@@ -14,6 +14,8 @@
 /**
  * A default integration with {@link BakuActivityTrait} extending {@link android.app.Activity}. Most
  * activities with distributed state should inherit from this.
+ *
+ * @see io.v.baku.toolkit
  */
 @Slf4j
 public abstract class BakuActivity extends VActivity implements BakuActivityTrait<Activity> {
diff --git a/baku-toolkit/lib/src/main/java/io/v/baku/toolkit/BakuActivityMixin.java b/baku-toolkit/lib/src/main/java/io/v/baku/toolkit/BakuActivityMixin.java
index 8bcbdb6..f222070 100644
--- a/baku-toolkit/lib/src/main/java/io/v/baku/toolkit/BakuActivityMixin.java
+++ b/baku-toolkit/lib/src/main/java/io/v/baku/toolkit/BakuActivityMixin.java
@@ -19,7 +19,7 @@
 import rx.subscriptions.CompositeSubscription;
 
 /**
- * Activity trait for activities with distributed UI state. By default, shared state is stored
+ * Activity mix-in for activities with distributed UI state. By default, shared state is stored
  * in Syncbase under <i>app.package.name</i>/db/ui.
  * <p>
  * Default activity extensions incorporating this mix-in are available:
@@ -29,7 +29,11 @@
  * </ul>
  * <p>
  * Since Java doesn't actually support multiple inheritance, clients requiring custom inheritance
- * hierarchies will need to wire in manually, like any of the examples above.
+ * hierarchies will need to wire in manually, like any of the examples above. Alternatively, this
+ * class may be used via pure composition, as detailed at
+ * {@link BakuActivityMixin#BakuActivityMixin(Activity, Bundle)}.
+ *
+ * @see io.v.baku.toolkit
  */
 @Accessors(prefix = "m")
 @Slf4j
@@ -70,7 +74,7 @@
      *     private BakuActivityTrait<SampleCompositionActivity> mBaku;
      *
      *     &#64;Override
-     *     protected void onCreate(Bundle savedInstanceState) {
+     *     protected void onCreate(final Bundle savedInstanceState) {
      *         super.onCreate(savedInstanceState);
      *         setContentView(R.layout.activity_hello);
      *
diff --git a/baku-toolkit/lib/src/main/java/io/v/baku/toolkit/BakuActivityTrait.java b/baku-toolkit/lib/src/main/java/io/v/baku/toolkit/BakuActivityTrait.java
index 9fbd4ec..9967814 100644
--- a/baku-toolkit/lib/src/main/java/io/v/baku/toolkit/BakuActivityTrait.java
+++ b/baku-toolkit/lib/src/main/java/io/v/baku/toolkit/BakuActivityTrait.java
@@ -13,6 +13,9 @@
 import io.v.baku.toolkit.syncbase.BakuTable;
 import rx.subscriptions.CompositeSubscription;
 
+/**
+ * @see BakuActivityMixin
+ */
 public interface BakuActivityTrait<T extends Activity> extends AutoCloseable {
     VAndroidContextTrait<T> getVAndroidContextTrait();
     BakuSyncbase getSyncbase();
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 14220dd..85c0da8 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
@@ -14,6 +14,8 @@
 /**
  * A default integration with {@link BakuActivityTrait} extending
  * {@link android.support.v7.app.AppCompatActivity}.
+ *
+ * @see io.v.baku.toolkit
  */
 @Slf4j
 public abstract class BakuAppCompatActivity
diff --git a/baku-toolkit/lib/src/main/java/io/v/baku/toolkit/VAndroidContextMixin.java b/baku-toolkit/lib/src/main/java/io/v/baku/toolkit/VAndroidContextMixin.java
index c9bdbc6..03a3ad4 100644
--- a/baku-toolkit/lib/src/main/java/io/v/baku/toolkit/VAndroidContextMixin.java
+++ b/baku-toolkit/lib/src/main/java/io/v/baku/toolkit/VAndroidContextMixin.java
@@ -27,15 +27,15 @@
 import lombok.extern.slf4j.Slf4j;
 
 /**
- * Android context mix-in incorporating common Vanadium utilities:
+ * Android context mix-in incorporating common Vanadium utilities. These include:
  * <ul>
  * <li>Vanadium initialization during {@code onCreate}; context available via
  * {@code getVContext}</li>
- * <li>Blessings management, available via {@code getBlessingsProvider().getRxBlessings}.
- * Upon {@code subscribe}, blessings are refreshed from the {@code BlessingsManager} or sought from
- * the {@code BlessingsProvider} (by default, the Account Manager).</li>
+ * <li>Blessings management, available via {@link BlessingsProvider#getRxBlessings()
+ * getBlessingsProvider().getRxBlessings()}. Upon {@code subscribe}, blessings are refreshed from
+ * the {@code BlessingsManager} or sought from the {@code BlessingsProvider} (by default, the
+ * Vanadium {@link io.v.android.libs.security.BlessingsManager}).</li>
  * </ul>
- * <p>
  * Default activity extensions incorporating this mix-in are available:
  * <ul>
  * <li>{@link VActivity} (extends {@link Activity})</li>
diff --git a/baku-toolkit/lib/src/main/java/io/v/baku/toolkit/bind/doc-files/bindings.png b/baku-toolkit/lib/src/main/java/io/v/baku/toolkit/bind/doc-files/bindings.png
new file mode 100644
index 0000000..bbfad53
--- /dev/null
+++ b/baku-toolkit/lib/src/main/java/io/v/baku/toolkit/bind/doc-files/bindings.png
Binary files differ
diff --git a/baku-toolkit/lib/src/main/java/io/v/baku/toolkit/bind/doc-files/mvvm.png b/baku-toolkit/lib/src/main/java/io/v/baku/toolkit/bind/doc-files/mvvm.png
new file mode 100644
index 0000000..25b2909
--- /dev/null
+++ b/baku-toolkit/lib/src/main/java/io/v/baku/toolkit/bind/doc-files/mvvm.png
Binary files differ
diff --git a/baku-toolkit/lib/src/main/java/io/v/baku/toolkit/bind/package-info.java b/baku-toolkit/lib/src/main/java/io/v/baku/toolkit/bind/package-info.java
index 4bdca83..10ff1a4 100644
--- a/baku-toolkit/lib/src/main/java/io/v/baku/toolkit/bind/package-info.java
+++ b/baku-toolkit/lib/src/main/java/io/v/baku/toolkit/bind/package-info.java
@@ -3,10 +3,44 @@
 // license that can be found in the LICENSE file.
 
 /**
- * Constructs:
- * <ul>
- * <li>Binding - maps one or more controls/properties to a Syncbase row.</li>
- * <li>Coordination policy - integrates uplinks and downlinks.</li>
- * </ul>
+ * These classes provide bindings between Android widgets and Syncbase data. For the reasons
+ * outlined in {@link io.v.rx.syncbase}, Vanadium state distribution with Syncbase would ideally be
+ * done with pure FRP <a href="https://en.wikipedia.org/wiki/Model%E2%80%93view%E2%80%93viewmodel"
+ * target="_blank">MVVM</a>, with distributed state elements modeled in Syncbase.
+ * <p>
+ * <img src="doc-files/mvvm.png">
+ * <p>
+ * <b>Fig: Ideal MVVM for distributed apps</b>
+ * <p>
+ * However, while this is easily accomplished with
+ * <a href="https://flutter.io/" target="_blank">Flutter</a>, the Baku Toolkit would need to
+ * implement an Android viewmodel layer to achieve the same for Android Java, which starts to amount
+ * to reimplementing Flutter for Java. Instead, the Baku Android Toolkit offers data bindings that
+ * allow Syncbase to drive more conventional Android Java UI widgets, and to allow those widgets to
+ * update distributed state in Syncbase.
+ * <p>
+ * <img src="doc-files/bindings.png">
+ * <p>
+ * <b>Fig: Baku data bindings without viewmodel</b>
+ * <p>
+ * Even though these data bindings are not true MVVM, app developers are encouraged to treat them
+ * declaratively, and to make use of pure functional transformations wherever possible to simplify
+ * their code. Imperative code is however still useful for Android initialization, implementing
+ * reactive widget update logic, and writing to Syncbase.
+ * <p>
+ * Data bindings are offered to client applications via builders. Many facets of bindings are
+ * derived from their usage context. For example, {@code bindTo(...)} methods perform type
+ * introspection to construct appropriate binding types for the widget being bound (and possibly the
+ * row type being bound to). In the future, we may add a plug-in to preprocess Android layout markup
+ * similar to the <a href="http://developer.android.com/tools/data-binding/guide.html"
+ * target="_blank">Android Data Binding Library</a>.
+ * <p>
+ * At present, for simplicity, each data binding that reads from Syncbase has its own Syncbase watch
+ * stream. If this ends up wasting resources and degrading performance, we can optimize to minimize
+ * the number of watch streams and broadcast filtered streams to each data binding.
+ * <p>
+ * Offering data bindings rather than pure functional MVVM transforms does introduce some
+ * coordination concerns between read and write bindings. Strategies for dealing with coordination
+ * are included in the toolkit.
  */
 package io.v.baku.toolkit.bind;
\ No newline at end of file
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
new file mode 100644
index 0000000..83e196e
--- /dev/null
+++ b/baku-toolkit/lib/src/main/java/io/v/baku/toolkit/package-info.java
@@ -0,0 +1,44 @@
+// 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.
+
+/**
+ * This package is the entry point into the Baku Toolkit. The easiest way for an application to take
+ * advantage of Baku is for its activities with distributed state to inherit from
+ * {@link io.v.baku.toolkit.BakuActivity} (or {@link io.v.baku.toolkit.BakuAppCompatActivity}; see
+ * {@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.BakuActivityMixin#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 {@code "text"} to the text of a
+ * {@link android.widget.TextView} with ID {@code textView}:
+ * <pre><code>
+ * &#64;Override
+ * protected void onCreate(final Bundle savedInstanceState) {
+ *     super.onCreate(savedInstanceState);
+ *     setContentView(R.layout.activity_layout);
+ *
+ *     binder().key("text")
+ *             .bindTo(R.id.textView);
+ *     }
+ * }
+ * </code></pre>
+ * Collection bindings (from vector data to list/recycler views) are similarly exposed through a
+ * {@link io.v.baku.toolkit.BakuActivityMixin#collectionBinder() collectionBinder()} builder. Writes
+ * can be performed directly via {@link io.v.baku.toolkit.syncbase.BakuTable#put(java.lang.String,
+ * java.lang.Object) getSyncbaseTable().put(key, value)}. More information about data bindings is
+ * available in the {@link io.v.baku.toolkit.bind} package documentation.
+ * <p>
+ * The Baku Toolkit creates a Syncbase table to use by default for data binding, and creates and
+ * manages a default {@linkplain io.v.rx.syncbase.UserCloudSyncgroup global user-level cloud
+ * syncgroup} to sync distributed data across all instances of the application belonging to a user.
+ * <p>
+ * Baku components are built in layers bundling common sets of functionality. This allows
+ * application developers the flexibility to selectively interact with APIs when they need to work
+ * around our high-level abstractions which potentially don't meet their use cases.
+ * <p>
+ * Sample code is available in the
+ * <a href="https://vanadium.googlesource.com/release.projects.baku/" target="_blank">baku projects
+ * repo</a>.
+ */
+package io.v.baku.toolkit;
\ No newline at end of file
diff --git a/baku-toolkit/lib/src/main/java/io/v/baku/toolkit/syncbase/package-info.java b/baku-toolkit/lib/src/main/java/io/v/baku/toolkit/syncbase/package-info.java
index 26d08b8..f9f2953 100644
--- a/baku-toolkit/lib/src/main/java/io/v/baku/toolkit/syncbase/package-info.java
+++ b/baku-toolkit/lib/src/main/java/io/v/baku/toolkit/syncbase/package-info.java
@@ -3,8 +3,8 @@
 // license that can be found in the LICENSE file.
 
 /**
- * For each {@link io.v.rx.syncbase.SyncbaseEntity RxSyncbase entity} class, this package adds a
- * {@link io.v.baku.toolkit.BakuActivityTrait} as context information from which to derive other
+ * For each {@linkplain io.v.rx.syncbase.SyncbaseEntity RxSyncbase entity} class, this package adds
+ * a {@link io.v.baku.toolkit.BakuActivityTrait} as context information from which to derive other
  * dependencies and to use for error handling. This allows Baku client code to use Syncbase more
  * easily, without needing to explicitly subscribe error handlers for every operation. For more
  * information, see {@link io.v.baku.toolkit.syncbase.BakuTable#exec(rx.functions.Func1)}.
diff --git a/baku-toolkit/lib/src/main/java/overview.html b/baku-toolkit/lib/src/main/java/overview.html
new file mode 100644
index 0000000..0548c5f
--- /dev/null
+++ b/baku-toolkit/lib/src/main/java/overview.html
@@ -0,0 +1,14 @@
+<body>
+The Baku Android Toolkit includes software components facilitating the development of
+applications with distributed user interfaces. It is available from JCenter and Maven Central. The
+available versions are listed
+<a href="https://bintray.com/vanadium/io.v/baku-toolkit" target="_blank">here</a>. To use the Baku
+Toolkit from an Android Java project, ensure that the {@code build.gradle} has either
+{@code jcenter()} or {@code mavenCentral()} in its repositories, add
+{@code 'io.v:baku-toolkit:version'} as a {@code compile} dependency, and bind an
+<a href="http://www.slf4j.org/" target="_blank">SLF4J</a> logger as an APK dependency, like
+{@code apk ('org.slf4j:slf4j-android:1.7.12')}.
+
+<p>
+    For common usage, see the {@link io.v.baku.toolkit} package docs.
+</body>
\ No newline at end of file