You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@beam.apache.org by bc...@apache.org on 2016/04/28 01:58:19 UTC

[1/3] incubator-beam git commit: Reduce overloaded methods in DisplayData

Repository: incubator-beam
Updated Branches:
  refs/heads/master a9387fcaa -> 81bf4d981


http://git-wip-us.apache.org/repos/asf/incubator-beam/blob/47c7abca/sdks/java/core/src/test/java/org/apache/beam/sdk/io/BoundedReadFromUnboundedSourceTest.java
----------------------------------------------------------------------
diff --git a/sdks/java/core/src/test/java/org/apache/beam/sdk/io/BoundedReadFromUnboundedSourceTest.java b/sdks/java/core/src/test/java/org/apache/beam/sdk/io/BoundedReadFromUnboundedSourceTest.java
index f7949e7..774968f 100644
--- a/sdks/java/core/src/test/java/org/apache/beam/sdk/io/BoundedReadFromUnboundedSourceTest.java
+++ b/sdks/java/core/src/test/java/org/apache/beam/sdk/io/BoundedReadFromUnboundedSourceTest.java
@@ -75,7 +75,7 @@ public class BoundedReadFromUnboundedSourceTest implements Serializable{
     TestCountingSource src = new TestCountingSource(1234) {
       @Override
       public void populateDisplayData(DisplayData.Builder builder) {
-        builder.add("foo", "bar");
+        builder.add(DisplayData.item("foo", "bar"));
       }
     };
 

http://git-wip-us.apache.org/repos/asf/incubator-beam/blob/47c7abca/sdks/java/core/src/test/java/org/apache/beam/sdk/io/CompressedSourceTest.java
----------------------------------------------------------------------
diff --git a/sdks/java/core/src/test/java/org/apache/beam/sdk/io/CompressedSourceTest.java b/sdks/java/core/src/test/java/org/apache/beam/sdk/io/CompressedSourceTest.java
index 36ef4b3..76e547f 100644
--- a/sdks/java/core/src/test/java/org/apache/beam/sdk/io/CompressedSourceTest.java
+++ b/sdks/java/core/src/test/java/org/apache/beam/sdk/io/CompressedSourceTest.java
@@ -343,7 +343,7 @@ public class CompressedSourceTest {
     ByteSource inputSource = new ByteSource("foobar.txt", 1) {
       @Override
       public void populateDisplayData(DisplayData.Builder builder) {
-        builder.add("foo", "bar");
+        builder.add(DisplayData.item("foo", "bar"));
       }
     };
 

http://git-wip-us.apache.org/repos/asf/incubator-beam/blob/47c7abca/sdks/java/core/src/test/java/org/apache/beam/sdk/io/ReadTest.java
----------------------------------------------------------------------
diff --git a/sdks/java/core/src/test/java/org/apache/beam/sdk/io/ReadTest.java b/sdks/java/core/src/test/java/org/apache/beam/sdk/io/ReadTest.java
index dd12bf4..237c025 100644
--- a/sdks/java/core/src/test/java/org/apache/beam/sdk/io/ReadTest.java
+++ b/sdks/java/core/src/test/java/org/apache/beam/sdk/io/ReadTest.java
@@ -74,13 +74,13 @@ public class ReadTest implements Serializable{
     SerializableBoundedSource boundedSource = new SerializableBoundedSource() {
       @Override
       public void populateDisplayData(DisplayData.Builder builder) {
-        builder.add("foo", "bar");
+        builder.add(DisplayData.item("foo", "bar"));
       }
     };
     SerializableUnboundedSource unboundedSource = new SerializableUnboundedSource() {
       @Override
       public void populateDisplayData(DisplayData.Builder builder) {
-        builder.add("foo", "bar");
+        builder.add(DisplayData.item("foo", "bar"));
       }
     };
     Duration maxReadTime = Duration.standardMinutes(2345);

http://git-wip-us.apache.org/repos/asf/incubator-beam/blob/47c7abca/sdks/java/core/src/test/java/org/apache/beam/sdk/io/WriteTest.java
----------------------------------------------------------------------
diff --git a/sdks/java/core/src/test/java/org/apache/beam/sdk/io/WriteTest.java b/sdks/java/core/src/test/java/org/apache/beam/sdk/io/WriteTest.java
index a95ef95..66cad60 100644
--- a/sdks/java/core/src/test/java/org/apache/beam/sdk/io/WriteTest.java
+++ b/sdks/java/core/src/test/java/org/apache/beam/sdk/io/WriteTest.java
@@ -164,7 +164,7 @@ public class WriteTest {
     TestSink sink = new TestSink() {
       @Override
       public void populateDisplayData(DisplayData.Builder builder) {
-        builder.add("foo", "bar");
+        builder.add(DisplayData.item("foo", "bar"));
       }
     };
     Write.Bound<String> write = Write.to(sink);

http://git-wip-us.apache.org/repos/asf/incubator-beam/blob/47c7abca/sdks/java/core/src/test/java/org/apache/beam/sdk/transforms/CombineFnsTest.java
----------------------------------------------------------------------
diff --git a/sdks/java/core/src/test/java/org/apache/beam/sdk/transforms/CombineFnsTest.java b/sdks/java/core/src/test/java/org/apache/beam/sdk/transforms/CombineFnsTest.java
index df5a828..486c738 100644
--- a/sdks/java/core/src/test/java/org/apache/beam/sdk/transforms/CombineFnsTest.java
+++ b/sdks/java/core/src/test/java/org/apache/beam/sdk/transforms/CombineFnsTest.java
@@ -340,8 +340,8 @@ public class  CombineFnsTest {
     @Override
     public void populateDisplayData(DisplayData.Builder builder) {
       builder
-          .add("uniqueKey" + id, value)
-          .add("sharedKey", value);
+          .add(DisplayData.item("uniqueKey" + id, value))
+          .add(DisplayData.item("sharedKey", value));
     }
   }
 

http://git-wip-us.apache.org/repos/asf/incubator-beam/blob/47c7abca/sdks/java/core/src/test/java/org/apache/beam/sdk/transforms/CombineTest.java
----------------------------------------------------------------------
diff --git a/sdks/java/core/src/test/java/org/apache/beam/sdk/transforms/CombineTest.java b/sdks/java/core/src/test/java/org/apache/beam/sdk/transforms/CombineTest.java
index e3308e5..803daec 100644
--- a/sdks/java/core/src/test/java/org/apache/beam/sdk/transforms/CombineTest.java
+++ b/sdks/java/core/src/test/java/org/apache/beam/sdk/transforms/CombineTest.java
@@ -701,7 +701,7 @@ public class CombineTest implements Serializable {
     UniqueInts combineFn = new UniqueInts() {
       @Override
       public void populateDisplayData(DisplayData.Builder builder) {
-        builder.add("fnMetadata", "foobar");
+        builder.add(DisplayData.item("fnMetadata", "foobar"));
       }
     };
     Combine.Globally<?, ?> combine = Combine.globally(combineFn)

http://git-wip-us.apache.org/repos/asf/incubator-beam/blob/47c7abca/sdks/java/core/src/test/java/org/apache/beam/sdk/transforms/IntraBundleParallelizationTest.java
----------------------------------------------------------------------
diff --git a/sdks/java/core/src/test/java/org/apache/beam/sdk/transforms/IntraBundleParallelizationTest.java b/sdks/java/core/src/test/java/org/apache/beam/sdk/transforms/IntraBundleParallelizationTest.java
index 4810513..66b189a 100644
--- a/sdks/java/core/src/test/java/org/apache/beam/sdk/transforms/IntraBundleParallelizationTest.java
+++ b/sdks/java/core/src/test/java/org/apache/beam/sdk/transforms/IntraBundleParallelizationTest.java
@@ -227,7 +227,7 @@ public class IntraBundleParallelizationTest {
 
       @Override
       public void populateDisplayData(DisplayData.Builder builder) {
-        builder.add("foo", "bar");
+        builder.add(DisplayData.item("foo", "bar"));
       }
     };
 

http://git-wip-us.apache.org/repos/asf/incubator-beam/blob/47c7abca/sdks/java/core/src/test/java/org/apache/beam/sdk/transforms/ParDoTest.java
----------------------------------------------------------------------
diff --git a/sdks/java/core/src/test/java/org/apache/beam/sdk/transforms/ParDoTest.java b/sdks/java/core/src/test/java/org/apache/beam/sdk/transforms/ParDoTest.java
index fdf3ddf..9193267 100644
--- a/sdks/java/core/src/test/java/org/apache/beam/sdk/transforms/ParDoTest.java
+++ b/sdks/java/core/src/test/java/org/apache/beam/sdk/transforms/ParDoTest.java
@@ -1537,7 +1537,7 @@ public class ParDoTest implements Serializable {
 
       @Override
       public void populateDisplayData(Builder builder) {
-        builder.add("doFnMetadata", "bar");
+        builder.add(DisplayData.item("doFnMetadata", "bar"));
       }
     };
 
@@ -1560,7 +1560,7 @@ public class ParDoTest implements Serializable {
 
       @Override
       public void populateDisplayData(Builder builder) {
-        builder.add("fnMetadata", "foobar");
+        builder.add(DisplayData.item("fnMetadata", "foobar"));
       }
     };
 
@@ -1579,7 +1579,7 @@ public class ParDoTest implements Serializable {
 
       @Override
       public void populateDisplayData(Builder builder) {
-        builder.add("fnMetadata", "foobar");
+        builder.add(DisplayData.item("fnMetadata", "foobar"));
       }
     };
 

http://git-wip-us.apache.org/repos/asf/incubator-beam/blob/47c7abca/sdks/java/core/src/test/java/org/apache/beam/sdk/transforms/display/DisplayDataMatchers.java
----------------------------------------------------------------------
diff --git a/sdks/java/core/src/test/java/org/apache/beam/sdk/transforms/display/DisplayDataMatchers.java b/sdks/java/core/src/test/java/org/apache/beam/sdk/transforms/display/DisplayDataMatchers.java
index 90e4441..c47b4c7 100644
--- a/sdks/java/core/src/test/java/org/apache/beam/sdk/transforms/display/DisplayDataMatchers.java
+++ b/sdks/java/core/src/test/java/org/apache/beam/sdk/transforms/display/DisplayDataMatchers.java
@@ -47,7 +47,13 @@ public class DisplayDataMatchers {
    * Creates a matcher that matches if the examined {@link DisplayData} contains any items.
    */
   public static Matcher<DisplayData> hasDisplayItem() {
-    return hasDisplayItem(Matchers.any(DisplayData.Item.class));
+    return new FeatureMatcher<DisplayData, Collection<DisplayData.Item<?>>>(
+        Matchers.not(Matchers.empty()), "DisplayData", "DisplayData") {
+      @Override
+      protected Collection<Item<?>> featureValueOf(DisplayData actual) {
+        return actual.items();
+      }
+    };
   }
 
   /**
@@ -119,14 +125,14 @@ public class DisplayDataMatchers {
    * Creates a matcher that matches if the examined {@link DisplayData} contains any item
    * matching the specified {@code itemMatcher}.
    */
-  public static Matcher<DisplayData> hasDisplayItem(Matcher<DisplayData.Item> itemMatcher) {
+  public static Matcher<DisplayData> hasDisplayItem(Matcher<DisplayData.Item<?>> itemMatcher) {
     return new HasDisplayDataItemMatcher(itemMatcher);
   }
 
   private static class HasDisplayDataItemMatcher extends TypeSafeDiagnosingMatcher<DisplayData> {
-    private final Matcher<Item> itemMatcher;
+    private final Matcher<Item<?>> itemMatcher;
 
-    private HasDisplayDataItemMatcher(Matcher<DisplayData.Item> itemMatcher) {
+    private HasDisplayDataItemMatcher(Matcher<DisplayData.Item<?>> itemMatcher) {
       this.itemMatcher = itemMatcher;
     }
 
@@ -138,7 +144,7 @@ public class DisplayDataMatchers {
 
     @Override
     protected boolean matchesSafely(DisplayData data, Description mismatchDescription) {
-      Collection<Item> items = data.items();
+      Collection<Item<?>> items = data.items();
       boolean isMatch = Matchers.hasItem(itemMatcher).matches(items);
       if (!isMatch) {
         mismatchDescription.appendText("found " + items.size() + " non-matching item(s):\n");
@@ -205,8 +211,8 @@ public class DisplayDataMatchers {
       private DisplayDataComparison checkSubset(
           DisplayData displayData, DisplayData included) {
         DisplayDataComparison comparison = new DisplayDataComparison(displayData.items());
-        for (Item item : included.items()) {
-          Item matchedItem = displayData.asMap().get(
+        for (Item<?> item : included.items()) {
+          Item<?> matchedItem = displayData.asMap().get(
               DisplayData.Identifier.of(item.getNamespace(), item.getKey()));
 
           if (matchedItem != null) {
@@ -220,19 +226,19 @@ public class DisplayDataMatchers {
       }
 
       class DisplayDataComparison {
-        Collection<DisplayData.Item> missingItems;
-        Collection<DisplayData.Item> unmatchedItems;
+        Collection<DisplayData.Item<?>> missingItems;
+        Collection<DisplayData.Item<?>> unmatchedItems;
 
-        DisplayDataComparison(Collection<Item> superset) {
+        DisplayDataComparison(Collection<Item<?>> superset) {
           missingItems = Sets.newHashSet();
           unmatchedItems = Sets.newHashSet(superset);
         }
 
-        void matched(Item supersetItem) {
+        void matched(Item<?> supersetItem) {
           unmatchedItems.remove(supersetItem);
         }
 
-        void missing(Item subsetItem) {
+        void missing(Item<?> subsetItem) {
           missingItems.add(subsetItem);
         }
       }
@@ -243,7 +249,7 @@ public class DisplayDataMatchers {
    * Creates a matcher that matches if the examined {@link DisplayData.Item} contains a key
    * with the specified value.
    */
-  public static Matcher<DisplayData.Item> hasKey(String key) {
+  public static Matcher<DisplayData.Item<?>> hasKey(String key) {
     return hasKey(Matchers.is(key));
   }
 
@@ -251,10 +257,10 @@ public class DisplayDataMatchers {
    * Creates a matcher that matches if the examined {@link DisplayData.Item} contains a key
    * matching the specified key matcher.
    */
-  public static Matcher<DisplayData.Item> hasKey(Matcher<String> keyMatcher) {
-    return new FeatureMatcher<DisplayData.Item, String>(keyMatcher, "with key", "key") {
+  public static Matcher<DisplayData.Item<?>> hasKey(Matcher<String> keyMatcher) {
+    return new FeatureMatcher<DisplayData.Item<?>, String>(keyMatcher, "with key", "key") {
       @Override
-      protected String featureValueOf(DisplayData.Item actual) {
+      protected String featureValueOf(DisplayData.Item<?> actual) {
         return actual.getKey();
       }
     };
@@ -264,7 +270,7 @@ public class DisplayDataMatchers {
    * Creates a matcher that matches if the examined {@link DisplayData.Item} contains the
    * specified namespace.
    */
-  public static Matcher<DisplayData.Item> hasNamespace(Class<?> namespace) {
+  public static Matcher<DisplayData.Item<?>> hasNamespace(Class<?> namespace) {
     return hasNamespace(Matchers.<Class<?>>is(namespace));
   }
 
@@ -272,11 +278,11 @@ public class DisplayDataMatchers {
    * Creates a matcher that matches if the examined {@link DisplayData.Item} contains a namespace
    * matching the specified namespace matcher.
    */
-  public static Matcher<DisplayData.Item> hasNamespace(Matcher<Class<?>> namespaceMatcher) {
-    return new FeatureMatcher<DisplayData.Item, Class<?>>(
+  public static Matcher<DisplayData.Item<?>> hasNamespace(Matcher<Class<?>> namespaceMatcher) {
+    return new FeatureMatcher<DisplayData.Item<?>, Class<?>>(
         namespaceMatcher, "display item with namespace", "namespace") {
       @Override
-      protected Class<?> featureValueOf(DisplayData.Item actual) {
+      protected Class<?> featureValueOf(DisplayData.Item<?> actual) {
         try {
           return Class.forName(actual.getNamespace());
         } catch (ClassNotFoundException e) {
@@ -290,7 +296,7 @@ public class DisplayDataMatchers {
    * Creates a matcher that matches if the examined {@link DisplayData.Item} matches the
    * specified type.
    */
-  public static Matcher<DisplayData.Item> hasType(DisplayData.Type type) {
+  public static Matcher<DisplayData.Item<?>> hasType(DisplayData.Type type) {
     return hasType(Matchers.is(type));
   }
 
@@ -298,11 +304,11 @@ public class DisplayDataMatchers {
    * Creates a matcher that matches if the examined {@link DisplayData.Item} has a type
    * matching the specified type matcher.
    */
-  public static Matcher<DisplayData.Item> hasType(Matcher<DisplayData.Type> typeMatcher) {
-    return new FeatureMatcher<DisplayData.Item, DisplayData.Type>(
+  public static Matcher<DisplayData.Item<?>> hasType(Matcher<DisplayData.Type> typeMatcher) {
+    return new FeatureMatcher<DisplayData.Item<?>, DisplayData.Type>(
             typeMatcher, "with type", "type") {
       @Override
-      protected DisplayData.Type featureValueOf(DisplayData.Item actual) {
+      protected DisplayData.Type featureValueOf(DisplayData.Item<?> actual) {
         return actual.getType();
       }
     };
@@ -313,7 +319,7 @@ public class DisplayDataMatchers {
    * value.
    */
 
-  public static Matcher<DisplayData.Item> hasValue(Object value) {
+  public static Matcher<DisplayData.Item<?>> hasValue(Object value) {
     return hasValue(Matchers.is(value));
   }
 
@@ -321,11 +327,11 @@ public class DisplayDataMatchers {
    * Creates a matcher that matches if the examined {@link DisplayData.Item} contains a value
    * matching the specified value matcher.
    */
-  public static <T> Matcher<DisplayData.Item> hasValue(Matcher<T> valueMatcher) {
-    return new FeatureMatcher<DisplayData.Item, T>(
+  public static <T> Matcher<DisplayData.Item<?>> hasValue(Matcher<T> valueMatcher) {
+    return new FeatureMatcher<DisplayData.Item<?>, T>(
             valueMatcher, "with value", "value") {
       @Override
-      protected T featureValueOf(DisplayData.Item actual) {
+      protected T featureValueOf(DisplayData.Item<?> actual) {
         @SuppressWarnings("unchecked")
         T value = (T) actual.getValue();
         return value;

http://git-wip-us.apache.org/repos/asf/incubator-beam/blob/47c7abca/sdks/java/core/src/test/java/org/apache/beam/sdk/transforms/display/DisplayDataMatchersTest.java
----------------------------------------------------------------------
diff --git a/sdks/java/core/src/test/java/org/apache/beam/sdk/transforms/display/DisplayDataMatchersTest.java b/sdks/java/core/src/test/java/org/apache/beam/sdk/transforms/display/DisplayDataMatchersTest.java
index 8bb65cc..f848c5e 100644
--- a/sdks/java/core/src/test/java/org/apache/beam/sdk/transforms/display/DisplayDataMatchersTest.java
+++ b/sdks/java/core/src/test/java/org/apache/beam/sdk/transforms/display/DisplayDataMatchersTest.java
@@ -24,8 +24,7 @@ import static org.apache.beam.sdk.transforms.display.DisplayDataMatchers.hasType
 import static org.apache.beam.sdk.transforms.display.DisplayDataMatchers.hasValue;
 import static org.apache.beam.sdk.transforms.display.DisplayDataMatchers.includesDisplayDataFrom;
 
-import static org.hamcrest.Matchers.containsString;
-import static org.hamcrest.core.StringStartsWith.startsWith;
+import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertFalse;
 import static org.junit.Assert.assertThat;
 
@@ -62,8 +61,8 @@ public class DisplayDataMatchersTest {
     matcher.describeTo(desc);
     matcher.describeMismatch(DisplayData.none(), mismatchDesc);
 
-    assertThat(desc.toString(), startsWith("display data with item: "));
-    assertThat(mismatchDesc.toString(), containsString("found 0 non-matching item(s)"));
+    assertEquals("DisplayData not an empty collection", desc.toString());
+    assertEquals("DisplayData was <[]>", mismatchDesc.toString());
   }
 
   @Test
@@ -82,7 +81,7 @@ public class DisplayDataMatchersTest {
     DisplayData data = DisplayData.from(new PTransform<PCollection<String>, PCollection<String>>() {
       @Override
       public void populateDisplayData(Builder builder) {
-        builder.add("foo", DisplayDataMatchersTest.class);
+        builder.add(DisplayData.item("foo", DisplayDataMatchersTest.class));
       }
     });
 
@@ -112,7 +111,7 @@ public class DisplayDataMatchersTest {
     final HasDisplayData subComponent = new HasDisplayData() {
       @Override
       public void populateDisplayData(Builder builder) {
-        builder.add("foo", "bar");
+        builder.add(DisplayData.item("foo", "bar"));
       }
     };
     HasDisplayData hasSubcomponent = new HasDisplayData() {
@@ -120,13 +119,13 @@ public class DisplayDataMatchersTest {
       public void populateDisplayData(Builder builder) {
         builder
           .include(subComponent)
-          .add("foo2", "bar2");
+          .add(DisplayData.item("foo2", "bar2"));
       }
     };
     HasDisplayData sameKeyDifferentNamespace = new HasDisplayData() {
       @Override
       public void populateDisplayData(Builder builder) {
-        builder.add("foo", "bar");
+        builder.add(DisplayData.item("foo", "bar"));
       }
     };
     Matcher<DisplayData> matcher = includesDisplayDataFrom(subComponent);
@@ -152,7 +151,7 @@ public class DisplayDataMatchersTest {
 
     @Override
     public void populateDisplayData(Builder builder) {
-      builder.add(key, value);
+      builder.add(DisplayData.item(key, value));
     }
   }
 }

http://git-wip-us.apache.org/repos/asf/incubator-beam/blob/47c7abca/sdks/java/core/src/test/java/org/apache/beam/sdk/transforms/display/DisplayDataTest.java
----------------------------------------------------------------------
diff --git a/sdks/java/core/src/test/java/org/apache/beam/sdk/transforms/display/DisplayDataTest.java b/sdks/java/core/src/test/java/org/apache/beam/sdk/transforms/display/DisplayDataTest.java
index 98604c7..108409f 100644
--- a/sdks/java/core/src/test/java/org/apache/beam/sdk/transforms/display/DisplayDataTest.java
+++ b/sdks/java/core/src/test/java/org/apache/beam/sdk/transforms/display/DisplayDataTest.java
@@ -86,7 +86,7 @@ public class DisplayDataTest {
         new HasDisplayData() {
           @Override
           public void populateDisplayData(DisplayData.Builder builder) {
-            builder.add("ExpectedAnswer", 42);
+            builder.add(DisplayData.item("ExpectedAnswer", 42));
           }
         };
 
@@ -94,7 +94,9 @@ public class DisplayDataTest {
         new HasDisplayData() {
           @Override
           public void populateDisplayData(DisplayData.Builder builder) {
-            builder.add("Location", "Seattle").add("Forecast", "Rain");
+            builder
+                .add(DisplayData.item("Location", "Seattle"))
+                .add(DisplayData.item("Forecast", "Rain"));
           }
         };
 
@@ -109,14 +111,14 @@ public class DisplayDataTest {
             builder
                 .include(subComponent1)
                 .include(subComponent2)
-                .add("minSproggles", 200)
-                  .withLabel("Mimimum Required Sproggles")
-                .add("fireLazers", true)
-                .addIfNotDefault("startTime", startTime, defaultStartTime)
-                .add("timeBomb", Instant.now().plus(Duration.standardDays(1)))
-                .add("filterLogic", subComponent1.getClass())
-                .add("serviceUrl", "google.com/fizzbang")
-                  .withLinkUrl("http://www.google.com/fizzbang");
+                .add(DisplayData.item("minSproggles", 200)
+                  .withLabel("Mimimum Required Sproggles"))
+                .add(DisplayData.item("fireLasers", true))
+                .addIfNotDefault(DisplayData.item("startTime", startTime), defaultStartTime)
+                .add(DisplayData.item("timeBomb", Instant.now().plus(Duration.standardDays(1))))
+                .add(DisplayData.item("filterLogic", subComponent1.getClass()))
+                .add(DisplayData.item("serviceUrl", "google.com/fizzbang")
+                  .withLinkUrl("http://www.google.com/fizzbang"));
           }
         };
 
@@ -142,12 +144,12 @@ public class DisplayDataTest {
   }
 
   @Test
-  public void testCanBuild() {
+  public void testCanBuildDisplayData() {
     DisplayData data =
         DisplayData.from(new HasDisplayData() {
               @Override
               public void populateDisplayData(DisplayData.Builder builder) {
-                builder.add("foo", "bar");
+                builder.add(DisplayData.item("foo", "bar"));
               }
             });
 
@@ -162,11 +164,11 @@ public class DisplayDataTest {
             new HasDisplayData() {
               @Override
               public void populateDisplayData(DisplayData.Builder builder) {
-                builder.add("foo", "bar");
+                builder.add(DisplayData.item("foo", "bar"));
               }
             });
 
-    Map<DisplayData.Identifier, DisplayData.Item> map = data.asMap();
+    Map<DisplayData.Identifier, DisplayData.Item<?>> map = data.asMap();
     assertEquals(map.size(), 1);
     assertThat(data, hasDisplayItem("foo", "bar"));
     assertEquals(map.values(), data.items());
@@ -178,15 +180,15 @@ public class DisplayDataTest {
     DisplayData data = DisplayData.from(new HasDisplayData() {
       @Override
       public void populateDisplayData(DisplayData.Builder builder) {
-        builder.add("now", value)
+        builder.add(DisplayData.item("now", value)
             .withLabel("the current instant")
             .withLinkUrl("http://time.gov")
-            .withNamespace(DisplayDataTest.class);
+            .withNamespace(DisplayDataTest.class));
       }
     });
 
     @SuppressWarnings("unchecked")
-    DisplayData.Item item = (DisplayData.Item) data.items().toArray()[0];
+    DisplayData.Item<?> item = (DisplayData.Item<?>) data.items().toArray()[0];
     assertThat(
         item,
         Matchers.allOf(
@@ -206,7 +208,7 @@ public class DisplayDataTest {
             new HasDisplayData() {
               @Override
               public void populateDisplayData(DisplayData.Builder builder) {
-                builder.add("foo", "bar");
+                builder.add(DisplayData.item("foo", "bar"));
               }
             });
 
@@ -221,20 +223,26 @@ public class DisplayDataTest {
       @Override
       public void populateDisplayData(Builder builder) {
         builder
-            .addIfNotDefault("defaultString", "foo", "foo")
-            .addIfNotDefault("notDefaultString", "foo", "notFoo")
-            .addIfNotDefault("defaultInteger", 1, 1)
-            .addIfNotDefault("notDefaultInteger", 1, 2)
-            .addIfNotDefault("defaultDouble", 123.4, 123.4)
-            .addIfNotDefault("notDefaultDouble", 123.4, 234.5)
-            .addIfNotDefault("defaultBoolean", true, true)
-            .addIfNotDefault("notDefaultBoolean", true, false)
-            .addIfNotDefault("defaultInstant", new Instant(0), new Instant(0))
-            .addIfNotDefault("notDefaultInstant", new Instant(0), Instant.now())
-            .addIfNotDefault("defaultDuration", Duration.ZERO, Duration.ZERO)
-            .addIfNotDefault("notDefaultDuration", Duration.millis(1234), Duration.ZERO)
-            .addIfNotDefault("defaultClass", DisplayDataTest.class, DisplayDataTest.class)
-            .addIfNotDefault("notDefaultClass", DisplayDataTest.class, null);
+            .addIfNotDefault(DisplayData.item("defaultString", "foo"), "foo")
+            .addIfNotDefault(DisplayData.item("notDefaultString", "foo"), "notFoo")
+            .addIfNotDefault(DisplayData.item("defaultInteger", 1), 1)
+            .addIfNotDefault(DisplayData.item("notDefaultInteger", 1), 2)
+            .addIfNotDefault(DisplayData.item("defaultDouble", 123.4), 123.4)
+            .addIfNotDefault(DisplayData.item("notDefaultDouble", 123.4), 234.5)
+            .addIfNotDefault(DisplayData.item("defaultBoolean", true), true)
+            .addIfNotDefault(DisplayData.item("notDefaultBoolean", true), false)
+            .addIfNotDefault(DisplayData.item("defaultInstant", new Instant(0)), new Instant(0))
+            .addIfNotDefault(DisplayData.item("notDefaultInstant", new Instant(0)), Instant.now())
+            .addIfNotDefault(DisplayData.item("defaultDuration", Duration.ZERO), Duration.ZERO)
+            .addIfNotDefault(
+                DisplayData.item("notDefaultDuration", Duration.millis(1234)),
+                Duration.ZERO)
+            .addIfNotDefault(
+                DisplayData.item("defaultClass", DisplayDataTest.class),
+                DisplayDataTest.class)
+            .addIfNotDefault(
+                DisplayData.item("notDefaultClass", DisplayDataTest.class),
+                null);
       }
     });
 
@@ -243,25 +251,58 @@ public class DisplayDataTest {
   }
 
   @Test
+  @SuppressWarnings("UnnecessaryBoxing")
+  public void testInterpolatedTypeDefaults() {
+    DisplayData data = DisplayData.from(new HasDisplayData() {
+      @Override
+      public void populateDisplayData(Builder builder) {
+        builder
+            .addIfNotDefault(DisplayData.item("integer", 123), 123)
+            .addIfNotDefault(DisplayData.item("Integer",
+                Integer.valueOf(123)),
+                Integer.valueOf(123))
+            .addIfNotDefault(DisplayData.item("long", 123L), 123L)
+            .addIfNotDefault(DisplayData.item("Long", Long.valueOf(123)), Long.valueOf(123))
+            .addIfNotDefault(DisplayData.item("float", 1.23f), 1.23f)
+            .addIfNotDefault(DisplayData.item("Float", Float.valueOf(1.23f)), Float.valueOf(1.23f))
+            .addIfNotDefault(DisplayData.item("double", 1.23), 1.23)
+            .addIfNotDefault(DisplayData.item("Double", Double.valueOf(1.23)), Double.valueOf(1.23))
+            .addIfNotDefault(DisplayData.item("boolean", true), true)
+            .addIfNotDefault(
+                DisplayData.item("Boolean", Boolean.valueOf(true)),
+                Boolean.valueOf(true))
+            .addIfNotDefault(
+                DisplayData.item("Class", DisplayDataTest.class),
+                DisplayDataTest.class)
+            .addIfNotDefault(
+                DisplayData.item("ClassForDisplay", ClassForDisplay.of(DisplayDataTest.class)),
+                ClassForDisplay.of(DisplayDataTest.class));
+      }
+    });
+
+    assertThat(data.items(), empty());
+  }
+
+  @Test
   public void testAddIfNotNull() {
     DisplayData data = DisplayData.from(new HasDisplayData() {
       @Override
       public void populateDisplayData(Builder builder) {
         builder
-            .addIfNotNull("nullString", (String) null)
-            .addIfNotNull("notNullString", "foo")
-            .addIfNotNull("nullLong", (Long) null)
-            .addIfNotNull("notNullLong", 1234L)
-            .addIfNotNull("nullDouble", (Double) null)
-            .addIfNotNull("notNullDouble", 123.4)
-            .addIfNotNull("nullBoolean", (Boolean) null)
-            .addIfNotNull("notNullBoolean", true)
-            .addIfNotNull("nullInstant", (Instant) null)
-            .addIfNotNull("notNullInstant", Instant.now())
-            .addIfNotNull("nullDuration", (Duration) null)
-            .addIfNotNull("notNullDuration", Duration.ZERO)
-            .addIfNotNull("nullClass", (Class<?>) null)
-            .addIfNotNull("notNullClass", DisplayDataTest.class);
+            .addIfNotNull(DisplayData.item("nullString", (String) null))
+            .addIfNotNull(DisplayData.item("notNullString", "foo"))
+            .addIfNotNull(DisplayData.item("nullLong", (Long) null))
+            .addIfNotNull(DisplayData.item("notNullLong", 1234L))
+            .addIfNotNull(DisplayData.item("nullDouble", (Double) null))
+            .addIfNotNull(DisplayData.item("notNullDouble", 123.4))
+            .addIfNotNull(DisplayData.item("nullBoolean", (Boolean) null))
+            .addIfNotNull(DisplayData.item("notNullBoolean", true))
+            .addIfNotNull(DisplayData.item("nullInstant", (Instant) null))
+            .addIfNotNull(DisplayData.item("notNullInstant", Instant.now()))
+            .addIfNotNull(DisplayData.item("nullDuration", (Duration) null))
+            .addIfNotNull(DisplayData.item("notNullDuration", Duration.ZERO))
+            .addIfNotNull(DisplayData.item("nullClass", (Class<?>) null))
+            .addIfNotNull(DisplayData.item("notNullClass", DisplayDataTest.class));
       }
     });
 
@@ -274,10 +315,10 @@ public class DisplayDataTest {
     HasDisplayData component = new HasDisplayData() {
       @Override
       public void populateDisplayData(Builder builder) {
-        builder.addIfNotNull("nullItem", (Class<?>) null)
+        builder.addIfNotNull(DisplayData.item("nullItem", (Class<?>) null)
             .withLinkUrl("http://abc")
             .withNamespace(DisplayDataTest.class)
-            .withLabel("Null item shoudl be safe");
+            .withLabel("Null item shoudl be safe"));
       }
     };
 
@@ -291,7 +332,7 @@ public class DisplayDataTest {
         new HasDisplayData() {
           @Override
           public void populateDisplayData(DisplayData.Builder builder) {
-            builder.add("foo", "bar");
+            builder.add(DisplayData.item("foo", "bar"));
           }
         };
 
@@ -312,7 +353,7 @@ public class DisplayDataTest {
     final HasDisplayData subComponent = new HasDisplayData() {
         @Override
         public void populateDisplayData(DisplayData.Builder builder) {
-          builder.add("foo", "bar");
+          builder.add(DisplayData.item("foo", "bar"));
         }
     };
 
@@ -339,8 +380,8 @@ public class DisplayDataTest {
     DisplayData.from(new HasDisplayData() {
       @Override
       public void populateDisplayData(Builder builder) {
-        builder.add("foo", "bar")
-            .withNamespace((Class<?>) null);
+        builder.add(DisplayData.item("foo", "bar")
+            .withNamespace((Class<?>) null));
       }
     });
   }
@@ -358,28 +399,9 @@ public class DisplayDataTest {
 
   @Test
   public void testItemEquality() {
-    HasDisplayData component1 = new HasDisplayData() {
-      @Override
-      public void populateDisplayData(Builder builder) {
-        builder.add("foo", "bar");
-      }
-    };
-    HasDisplayData component2 = new HasDisplayData() {
-      @Override
-      public void populateDisplayData(Builder builder) {
-        builder.add("foo", "bar");
-      }
-    };
-
-    DisplayData component1DisplayData1 = DisplayData.from(component1);
-    DisplayData component1DisplayData2 = DisplayData.from(component1);
-    DisplayData component2DisplayData = DisplayData.from(component2);
-
     new EqualsTester()
-        .addEqualityGroup(
-            component1DisplayData1.items().toArray()[0],
-            component1DisplayData2.items().toArray()[0])
-        .addEqualityGroup(component2DisplayData.items().toArray()[0])
+        .addEqualityGroup(DisplayData.item("foo", "bar"), DisplayData.item("foo", "bar"))
+        .addEqualityGroup(DisplayData.item("foo", "barz"))
         .testEquals();
   }
 
@@ -388,13 +410,13 @@ public class DisplayDataTest {
     HasDisplayData component1 = new HasDisplayData() {
       @Override
       public void populateDisplayData(Builder builder) {
-        builder.add("foo", "bar");
+        builder.add(DisplayData.item("foo", "bar"));
       }
     };
     HasDisplayData component2 = new HasDisplayData() {
       @Override
       public void populateDisplayData(Builder builder) {
-        builder.add("foo", "bar");
+        builder.add(DisplayData.item("foo", "bar"));
       }
     };
 
@@ -415,11 +437,11 @@ public class DisplayDataTest {
             new HasDisplayData() {
               @Override
               public void populateDisplayData(DisplayData.Builder builder) {
-                builder.add("foo", "bar");
+                builder.add(DisplayData.item("foo", "bar"));
               }
             });
 
-    DisplayData.Item item = (DisplayData.Item) data.items().toArray()[0];
+    DisplayData.Item<?> item = (DisplayData.Item<?>) data.items().toArray()[0];
     final Pattern anonClassRegex = Pattern.compile(
         Pattern.quote(DisplayDataTest.class.getName()) + "\\$\\d+$");
     assertThat(item.getNamespace(), new CustomTypeSafeMatcher<String>(
@@ -440,12 +462,12 @@ public class DisplayDataTest {
               @Override
               public void populateDisplayData(DisplayData.Builder builder) {
                 builder
-                    .add("foo", "bar")
+                    .add(DisplayData.item("foo", "bar"))
                     .include(
                         new HasDisplayData() {
                           @Override
                           public void populateDisplayData(DisplayData.Builder builder) {
-                            builder.add("foo", "bar");
+                            builder.add(DisplayData.item("foo", "bar"));
                           }
                         });
               }
@@ -462,8 +484,8 @@ public class DisplayDataTest {
           @Override
           public void populateDisplayData(DisplayData.Builder builder) {
             builder
-              .add("foo", "bar")
-              .add("foo", "baz");
+              .add(DisplayData.item("foo", "bar"))
+              .add(DisplayData.item("foo", "baz"));
           }
         });
   }
@@ -475,9 +497,9 @@ public class DisplayDataTest {
           @Override
           public void populateDisplayData(DisplayData.Builder builder) {
             builder
-                .add("foo", "bar")
-                .add("foo", "baz")
-                  .withNamespace(DisplayDataTest.class);
+                .add(DisplayData.item("foo", "bar"))
+                .add(DisplayData.item("foo", "baz")
+                  .withNamespace(DisplayDataTest.class));
           }
         });
 
@@ -489,7 +511,7 @@ public class DisplayDataTest {
     HasDisplayData component = new HasDisplayData() {
       @Override
       public void populateDisplayData(DisplayData.Builder builder) {
-        builder.add("foo", "bar");
+        builder.add(DisplayData.item("foo", "bar"));
       }
     };
 
@@ -554,7 +576,7 @@ public class DisplayDataTest {
 
     @Override
     public void populateDisplayData(DisplayData.Builder builder) {
-      builder.add(key, value);
+      builder.add(DisplayData.item(key, value));
     }
 
     @Override
@@ -574,7 +596,9 @@ public class DisplayDataTest {
 
     @Override
     public void populateDisplayData(DisplayData.Builder builder) {
-      builder.add("id", getId()).include(subComponent);
+      builder
+          .add(DisplayData.item("id", getId()))
+          .include(subComponent);
     }
 
     abstract String getId();
@@ -588,18 +612,18 @@ public class DisplayDataTest {
               @Override
               public void populateDisplayData(DisplayData.Builder builder) {
                 builder
-                    .add("string", "foobar")
-                    .add("integer", 123)
-                    .add("float", 3.14)
-                    .add("boolean", true)
-                    .add("java_class", DisplayDataTest.class)
-                    .add("java_class2", ClassForDisplay.of(DisplayDataTest.class))
-                    .add("timestamp", Instant.now())
-                    .add("duration", Duration.standardHours(1));
+                    .add(DisplayData.item("string", "foobar"))
+                    .add(DisplayData.item("integer", 123))
+                    .add(DisplayData.item("float", 3.14))
+                    .add(DisplayData.item("boolean", true))
+                    .add(DisplayData.item("java_class", DisplayDataTest.class))
+                    .add(DisplayData.item("java_class2", ClassForDisplay.of(DisplayDataTest.class)))
+                    .add(DisplayData.item("timestamp", Instant.now()))
+                    .add(DisplayData.item("duration", Duration.standardHours(1)));
               }
             });
 
-    Collection<Item> items = data.items();
+    Collection<Item<?>> items = data.items();
     assertThat(
         items, hasItem(allOf(hasKey("string"), hasType(DisplayData.Type.STRING))));
     assertThat(
@@ -625,8 +649,8 @@ public class DisplayDataTest {
       @Override
       public void populateDisplayData(Builder builder) {
         builder
-            .add("integer", DisplayData.Type.INTEGER, 1234L)
-            .add("string", DisplayData.Type.STRING, "foobar");
+            .add(DisplayData.item("integer", DisplayData.Type.INTEGER, 1234L))
+            .add(DisplayData.item("string", DisplayData.Type.STRING, "foobar"));
       }
     });
 
@@ -690,7 +714,7 @@ public class DisplayDataTest {
     HasDisplayData component = new HasDisplayData() {
       @Override
       public void populateDisplayData(Builder builder) {
-        builder.add("integer", DisplayData.Type.INTEGER, "foobar");
+        builder.add(DisplayData.item("integer", DisplayData.Type.INTEGER, "foobar"));
       }
     };
 
@@ -725,13 +749,13 @@ public class DisplayDataTest {
       @Override
       public void populateDisplayData(DisplayData.Builder builder) {
         builder
-          .add("string", "foobar")
-          .add("integer", 123)
-          .add("float", 3.14)
-          .add("boolean", true)
-          .add("java_class", DisplayDataTest.class)
-          .add("timestamp", now)
-          .add("duration", oneHour);
+          .add(DisplayData.item("string", "foobar"))
+          .add(DisplayData.item("integer", 123))
+          .add(DisplayData.item("float", 3.14))
+          .add(DisplayData.item("boolean", true))
+          .add(DisplayData.item("java_class", DisplayDataTest.class))
+          .add(DisplayData.item("timestamp", now))
+          .add(DisplayData.item("duration", oneHour));
       }
     };
     DisplayData data = DisplayData.from(component);
@@ -751,7 +775,7 @@ public class DisplayDataTest {
         new HasDisplayData() {
           @Override
           public void populateDisplayData(DisplayData.Builder builder) {
-            builder.add("foo", "bar");
+            builder.add(DisplayData.item("foo", "bar"));
           }
         };
 
@@ -761,7 +785,7 @@ public class DisplayDataTest {
           public void populateDisplayData(DisplayData.Builder builder) {
             builder
               .include(subComponent)
-              .add("alpha", "bravo");
+              .add(DisplayData.item("alpha", "bravo"));
           }
         };
 
@@ -816,7 +840,7 @@ public class DisplayDataTest {
         new HasDisplayData() {
           @Override
           public void populateDisplayData(Builder builder) {
-            builder.add(null, "foo");
+            builder.add(DisplayData.item(null, "foo"));
           }
         });
   }
@@ -828,28 +852,28 @@ public class DisplayDataTest {
         @Override
         public void populateDisplayData(Builder builder) {
           try {
-            builder.add("key", (String) null);
+            builder.add(DisplayData.item("key", (String) null));
             throw new RuntimeException("Should throw on null string value");
           } catch (NullPointerException ex) {
             // Expected
           }
 
           try {
-            builder.add("key", (Class<?>) null);
+            builder.add(DisplayData.item("key", (Class<?>) null));
             throw new RuntimeException("Should throw on null class value");
           } catch (NullPointerException ex) {
             // Expected
           }
 
           try {
-            builder.add("key", (Duration) null);
+            builder.add(DisplayData.item("key", (Duration) null));
             throw new RuntimeException("Should throw on null duration value");
           } catch (NullPointerException ex) {
             // Expected
           }
 
           try {
-            builder.add("key", (Instant) null);
+            builder.add(DisplayData.item("key", (Instant) null));
             throw new RuntimeException("Should throw on null instant value");
           } catch (NullPointerException ex) {
             // Expected
@@ -864,9 +888,9 @@ public class DisplayDataTest {
       new HasDisplayData() {
         @Override
         public void populateDisplayData(Builder builder) {
-          builder.add("key", "value")
+          builder.add(DisplayData.item("key", "value")
               .withLabel(null)
-              .withLinkUrl(null);
+              .withLinkUrl(null));
         }
       });
 
@@ -885,16 +909,15 @@ public class DisplayDataTest {
       @Override
       public void populateDisplayData(Builder builder) {
         builder
-            .add("string", stringValue)
-            .add("long", intValue)
-            .add("double", floatValue)
-            .add("boolean", boolValue)
-            .add("instant", new Instant(0))
-            .add("duration", Duration.millis(durationMillis))
-            .add("class", DisplayDataTest.class)
+            .add(DisplayData.item("string", stringValue))
+            .add(DisplayData.item("long", intValue))
+            .add(DisplayData.item("double", floatValue))
+            .add(DisplayData.item("boolean", boolValue))
+            .add(DisplayData.item("instant", new Instant(0)))
+            .add(DisplayData.item("duration", Duration.millis(durationMillis)))
+            .add(DisplayData.item("class", DisplayDataTest.class)
               .withLinkUrl("http://abc")
-              .withLabel("baz")
-        ;
+              .withLabel("baz"));
       }
     };
     DisplayData data = DisplayData.from(component);
@@ -955,31 +978,31 @@ public class DisplayDataTest {
     return hasItem(jsonNode);
   }
 
-  private static Matcher<DisplayData.Item> hasLabel(Matcher<String> labelMatcher) {
-    return new FeatureMatcher<DisplayData.Item, String>(
+  private static Matcher<DisplayData.Item<?>> hasLabel(Matcher<String> labelMatcher) {
+    return new FeatureMatcher<DisplayData.Item<?>, String>(
         labelMatcher, "display item with label", "label") {
       @Override
-      protected String featureValueOf(DisplayData.Item actual) {
+      protected String featureValueOf(DisplayData.Item<?> actual) {
         return actual.getLabel();
       }
     };
   }
 
-  private static Matcher<DisplayData.Item> hasUrl(Matcher<String> urlMatcher) {
-    return new FeatureMatcher<DisplayData.Item, String>(
+  private static Matcher<DisplayData.Item<?>> hasUrl(Matcher<String> urlMatcher) {
+    return new FeatureMatcher<DisplayData.Item<?>, String>(
         urlMatcher, "display item with url", "URL") {
       @Override
-      protected String featureValueOf(DisplayData.Item actual) {
+      protected String featureValueOf(DisplayData.Item<?> actual) {
         return actual.getLinkUrl();
       }
     };
   }
 
-  private static  <T> Matcher<DisplayData.Item> hasShortValue(Matcher<T> valueStringMatcher) {
-    return new FeatureMatcher<DisplayData.Item, T>(
+  private static  <T> Matcher<DisplayData.Item<?>> hasShortValue(Matcher<T> valueStringMatcher) {
+    return new FeatureMatcher<DisplayData.Item<?>, T>(
         valueStringMatcher, "display item with short value", "short value") {
       @Override
-      protected T featureValueOf(DisplayData.Item actual) {
+      protected T featureValueOf(DisplayData.Item<?> actual) {
         @SuppressWarnings("unchecked")
         T shortValue = (T) actual.getShortValue();
         return shortValue;

http://git-wip-us.apache.org/repos/asf/incubator-beam/blob/47c7abca/sdks/java/io/google-cloud-platform/src/main/java/org/apache/beam/sdk/io/gcp/bigtable/BigtableIO.java
----------------------------------------------------------------------
diff --git a/sdks/java/io/google-cloud-platform/src/main/java/org/apache/beam/sdk/io/gcp/bigtable/BigtableIO.java b/sdks/java/io/google-cloud-platform/src/main/java/org/apache/beam/sdk/io/gcp/bigtable/BigtableIO.java
index f99eb1d..bf85dea 100644
--- a/sdks/java/io/google-cloud-platform/src/main/java/org/apache/beam/sdk/io/gcp/bigtable/BigtableIO.java
+++ b/sdks/java/io/google-cloud-platform/src/main/java/org/apache/beam/sdk/io/gcp/bigtable/BigtableIO.java
@@ -266,14 +266,14 @@ public class BigtableIO {
     public void populateDisplayData(DisplayData.Builder builder) {
       super.populateDisplayData(builder);
 
-      builder.add("tableId", tableId);
+      builder.add(DisplayData.item("tableId", tableId));
 
       if (options != null) {
-        builder.add("bigtableOptions", options.toString());
+        builder.add(DisplayData.item("bigtableOptions", options.toString()));
       }
 
       if (filter != null) {
-        builder.add("rowFilter", filter.toString());
+        builder.add(DisplayData.item("rowFilter", filter.toString()));
       }
     }
 
@@ -448,10 +448,10 @@ public class BigtableIO {
     public void populateDisplayData(DisplayData.Builder builder) {
       super.populateDisplayData(builder);
 
-      builder.add("tableId", tableId);
+      builder.add(DisplayData.item("tableId", tableId));
 
       if (options != null) {
-        builder.add("bigtableOptions", options.toString());
+        builder.add(DisplayData.item("bigtableOptions", options.toString()));
       }
     }
 



[3/3] incubator-beam git commit: This closes #247

Posted by bc...@apache.org.
This closes #247


Project: http://git-wip-us.apache.org/repos/asf/incubator-beam/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-beam/commit/81bf4d98
Tree: http://git-wip-us.apache.org/repos/asf/incubator-beam/tree/81bf4d98
Diff: http://git-wip-us.apache.org/repos/asf/incubator-beam/diff/81bf4d98

Branch: refs/heads/master
Commit: 81bf4d981a7d5d86955c02003fb615c4985552bb
Parents: a9387fc 47c7abc
Author: bchambers <bc...@google.com>
Authored: Wed Apr 27 16:44:28 2016 -0700
Committer: bchambers <bc...@google.com>
Committed: Wed Apr 27 16:44:28 2016 -0700

----------------------------------------------------------------------
 .../DataflowPipelineTranslatorTest.java         |  10 +-
 .../java/org/apache/beam/sdk/io/AvroIO.java     |  18 +-
 .../java/org/apache/beam/sdk/io/BigQueryIO.java |  20 +-
 .../sdk/io/BoundedReadFromUnboundedSource.java  |   6 +-
 .../apache/beam/sdk/io/CompressedSource.java    |   6 +-
 .../org/apache/beam/sdk/io/CountingInput.java   |   8 +-
 .../org/apache/beam/sdk/io/DatastoreIO.java     |  12 +-
 .../org/apache/beam/sdk/io/FileBasedSink.java   |   2 +-
 .../org/apache/beam/sdk/io/FileBasedSource.java |   2 +-
 .../apache/beam/sdk/io/OffsetBasedSource.java   |   6 +-
 .../java/org/apache/beam/sdk/io/PubsubIO.java   |  18 +-
 .../main/java/org/apache/beam/sdk/io/Read.java  |   4 +-
 .../java/org/apache/beam/sdk/io/TextIO.java     |  18 +-
 .../main/java/org/apache/beam/sdk/io/Write.java |   2 +-
 .../java/org/apache/beam/sdk/io/XmlSink.java    |   4 +-
 .../java/org/apache/beam/sdk/io/XmlSource.java  |   6 +-
 .../sdk/options/ProxyInvocationHandler.java     |  22 +-
 .../sdk/transforms/ApproximateQuantiles.java    |   4 +-
 .../beam/sdk/transforms/ApproximateUnique.java  |   4 +-
 .../org/apache/beam/sdk/transforms/Combine.java |  10 +-
 .../apache/beam/sdk/transforms/CombineFns.java  |   2 +-
 .../org/apache/beam/sdk/transforms/Filter.java  |   2 +-
 .../apache/beam/sdk/transforms/GroupByKey.java  |   2 +-
 .../transforms/IntraBundleParallelization.java  |   4 +-
 .../org/apache/beam/sdk/transforms/Max.java     |   2 +-
 .../org/apache/beam/sdk/transforms/Min.java     |   2 +-
 .../org/apache/beam/sdk/transforms/ParDo.java   |   2 +-
 .../apache/beam/sdk/transforms/Partition.java   |   4 +-
 .../org/apache/beam/sdk/transforms/Sample.java  |   4 +-
 .../org/apache/beam/sdk/transforms/Top.java     |   4 +-
 .../sdk/transforms/display/ClassForDisplay.java |   7 +-
 .../sdk/transforms/display/DisplayData.java     | 745 ++++++-------------
 .../sdk/transforms/display/HasDisplayData.java  |  12 +-
 .../transforms/windowing/CalendarWindows.java   |  15 +-
 .../sdk/transforms/windowing/FixedWindows.java  |   4 +-
 .../beam/sdk/transforms/windowing/Sessions.java |   2 +-
 .../transforms/windowing/SlidingWindows.java    |   6 +-
 .../beam/sdk/transforms/windowing/Window.java   |  12 +-
 .../io/BoundedReadFromUnboundedSourceTest.java  |   2 +-
 .../beam/sdk/io/CompressedSourceTest.java       |   2 +-
 .../java/org/apache/beam/sdk/io/ReadTest.java   |   4 +-
 .../java/org/apache/beam/sdk/io/WriteTest.java  |   2 +-
 .../beam/sdk/transforms/CombineFnsTest.java     |   4 +-
 .../apache/beam/sdk/transforms/CombineTest.java |   2 +-
 .../IntraBundleParallelizationTest.java         |   2 +-
 .../apache/beam/sdk/transforms/ParDoTest.java   |   6 +-
 .../transforms/display/DisplayDataMatchers.java |  62 +-
 .../display/DisplayDataMatchersTest.java        |  17 +-
 .../sdk/transforms/display/DisplayDataTest.java | 289 +++----
 .../beam/sdk/io/gcp/bigtable/BigtableIO.java    |  10 +-
 50 files changed, 601 insertions(+), 814 deletions(-)
----------------------------------------------------------------------



[2/3] incubator-beam git commit: Reduce overloaded methods in DisplayData

Posted by bc...@apache.org.
Reduce overloaded methods in DisplayData

Introduce `DisplayData#Item` which represents a single item of
`DisplayData`. Reduce the number of methods on `DisplayData#Builder` to
just deal with adding items, rather than needing per-type overrides.

Update all providers of `DisplayData` to use the new API.


Project: http://git-wip-us.apache.org/repos/asf/incubator-beam/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-beam/commit/47c7abca
Tree: http://git-wip-us.apache.org/repos/asf/incubator-beam/tree/47c7abca
Diff: http://git-wip-us.apache.org/repos/asf/incubator-beam/diff/47c7abca

Branch: refs/heads/master
Commit: 47c7abcacdd8ee1c14c2c8d94a263f96dfe5bf8d
Parents: a9387fc
Author: Scott Wegner <sw...@google.com>
Authored: Mon Apr 25 16:04:38 2016 -0700
Committer: bchambers <bc...@google.com>
Committed: Wed Apr 27 16:44:17 2016 -0700

----------------------------------------------------------------------
 .../DataflowPipelineTranslatorTest.java         |  10 +-
 .../java/org/apache/beam/sdk/io/AvroIO.java     |  18 +-
 .../java/org/apache/beam/sdk/io/BigQueryIO.java |  20 +-
 .../sdk/io/BoundedReadFromUnboundedSource.java  |   6 +-
 .../apache/beam/sdk/io/CompressedSource.java    |   6 +-
 .../org/apache/beam/sdk/io/CountingInput.java   |   8 +-
 .../org/apache/beam/sdk/io/DatastoreIO.java     |  12 +-
 .../org/apache/beam/sdk/io/FileBasedSink.java   |   2 +-
 .../org/apache/beam/sdk/io/FileBasedSource.java |   2 +-
 .../apache/beam/sdk/io/OffsetBasedSource.java   |   6 +-
 .../java/org/apache/beam/sdk/io/PubsubIO.java   |  18 +-
 .../main/java/org/apache/beam/sdk/io/Read.java  |   4 +-
 .../java/org/apache/beam/sdk/io/TextIO.java     |  18 +-
 .../main/java/org/apache/beam/sdk/io/Write.java |   2 +-
 .../java/org/apache/beam/sdk/io/XmlSink.java    |   4 +-
 .../java/org/apache/beam/sdk/io/XmlSource.java  |   6 +-
 .../sdk/options/ProxyInvocationHandler.java     |  22 +-
 .../sdk/transforms/ApproximateQuantiles.java    |   4 +-
 .../beam/sdk/transforms/ApproximateUnique.java  |   4 +-
 .../org/apache/beam/sdk/transforms/Combine.java |  10 +-
 .../apache/beam/sdk/transforms/CombineFns.java  |   2 +-
 .../org/apache/beam/sdk/transforms/Filter.java  |   2 +-
 .../apache/beam/sdk/transforms/GroupByKey.java  |   2 +-
 .../transforms/IntraBundleParallelization.java  |   4 +-
 .../org/apache/beam/sdk/transforms/Max.java     |   2 +-
 .../org/apache/beam/sdk/transforms/Min.java     |   2 +-
 .../org/apache/beam/sdk/transforms/ParDo.java   |   2 +-
 .../apache/beam/sdk/transforms/Partition.java   |   4 +-
 .../org/apache/beam/sdk/transforms/Sample.java  |   4 +-
 .../org/apache/beam/sdk/transforms/Top.java     |   4 +-
 .../sdk/transforms/display/ClassForDisplay.java |   7 +-
 .../sdk/transforms/display/DisplayData.java     | 745 ++++++-------------
 .../sdk/transforms/display/HasDisplayData.java  |  12 +-
 .../transforms/windowing/CalendarWindows.java   |  15 +-
 .../sdk/transforms/windowing/FixedWindows.java  |   4 +-
 .../beam/sdk/transforms/windowing/Sessions.java |   2 +-
 .../transforms/windowing/SlidingWindows.java    |   6 +-
 .../beam/sdk/transforms/windowing/Window.java   |  12 +-
 .../io/BoundedReadFromUnboundedSourceTest.java  |   2 +-
 .../beam/sdk/io/CompressedSourceTest.java       |   2 +-
 .../java/org/apache/beam/sdk/io/ReadTest.java   |   4 +-
 .../java/org/apache/beam/sdk/io/WriteTest.java  |   2 +-
 .../beam/sdk/transforms/CombineFnsTest.java     |   4 +-
 .../apache/beam/sdk/transforms/CombineTest.java |   2 +-
 .../IntraBundleParallelizationTest.java         |   2 +-
 .../apache/beam/sdk/transforms/ParDoTest.java   |   6 +-
 .../transforms/display/DisplayDataMatchers.java |  62 +-
 .../display/DisplayDataMatchersTest.java        |  17 +-
 .../sdk/transforms/display/DisplayDataTest.java | 289 +++----
 .../beam/sdk/io/gcp/bigtable/BigtableIO.java    |  10 +-
 50 files changed, 601 insertions(+), 814 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-beam/blob/47c7abca/runners/google-cloud-dataflow-java/src/test/java/org/apache/beam/runners/dataflow/DataflowPipelineTranslatorTest.java
----------------------------------------------------------------------
diff --git a/runners/google-cloud-dataflow-java/src/test/java/org/apache/beam/runners/dataflow/DataflowPipelineTranslatorTest.java b/runners/google-cloud-dataflow-java/src/test/java/org/apache/beam/runners/dataflow/DataflowPipelineTranslatorTest.java
index 3a39e41..58b38d2 100644
--- a/runners/google-cloud-dataflow-java/src/test/java/org/apache/beam/runners/dataflow/DataflowPipelineTranslatorTest.java
+++ b/runners/google-cloud-dataflow-java/src/test/java/org/apache/beam/runners/dataflow/DataflowPipelineTranslatorTest.java
@@ -874,10 +874,10 @@ public class DataflowPipelineTranslatorTest implements Serializable {
       @Override
       public void populateDisplayData(DisplayData.Builder builder) {
         builder
-            .add("foo", "bar")
-            .add("foo2", DataflowPipelineTranslatorTest.class)
+            .add(DisplayData.item("foo", "bar"))
+            .add(DisplayData.item("foo2", DataflowPipelineTranslatorTest.class)
                 .withLabel("Test Class")
-                .withLinkUrl("http://www.google.com");
+                .withLinkUrl("http://www.google.com"));
       }
     };
 
@@ -889,7 +889,7 @@ public class DataflowPipelineTranslatorTest implements Serializable {
 
       @Override
       public void populateDisplayData(DisplayData.Builder builder) {
-        builder.add("foo3", 1234);
+        builder.add(DisplayData.item("foo3", 1234));
       }
     };
 
@@ -915,8 +915,10 @@ public class DataflowPipelineTranslatorTest implements Serializable {
     Map<String, Object> parDo2Properties = steps.get(2).getProperties();
     assertThat(parDo1Properties, hasKey("display_data"));
 
+    @SuppressWarnings("unchecked")
     Collection<Map<String, String>> fn1displayData =
             (Collection<Map<String, String>>) parDo1Properties.get("display_data");
+    @SuppressWarnings("unchecked")
     Collection<Map<String, String>> fn2displayData =
             (Collection<Map<String, String>>) parDo2Properties.get("display_data");
 

http://git-wip-us.apache.org/repos/asf/incubator-beam/blob/47c7abca/sdks/java/core/src/main/java/org/apache/beam/sdk/io/AvroIO.java
----------------------------------------------------------------------
diff --git a/sdks/java/core/src/main/java/org/apache/beam/sdk/io/AvroIO.java b/sdks/java/core/src/main/java/org/apache/beam/sdk/io/AvroIO.java
index c706fc1..6b9f010 100644
--- a/sdks/java/core/src/main/java/org/apache/beam/sdk/io/AvroIO.java
+++ b/sdks/java/core/src/main/java/org/apache/beam/sdk/io/AvroIO.java
@@ -331,8 +331,8 @@ public class AvroIO {
       public void populateDisplayData(DisplayData.Builder builder) {
         super.populateDisplayData(builder);
         builder
-          .addIfNotNull("filePattern", filepattern)
-          .addIfNotDefault("validation", validate, true);
+          .addIfNotNull(DisplayData.item("filePattern", filepattern))
+          .addIfNotDefault(DisplayData.item("validation", validate), true);
       }
 
       @Override
@@ -694,12 +694,14 @@ public class AvroIO {
       public void populateDisplayData(DisplayData.Builder builder) {
         super.populateDisplayData(builder);
         builder
-            .add("schema", type)
-            .addIfNotNull("filePrefix", filenamePrefix)
-            .addIfNotDefault("shardNameTemplate", shardTemplate, DEFAULT_SHARD_TEMPLATE)
-            .addIfNotDefault("fileSuffix", filenameSuffix, "")
-            .addIfNotDefault("numShards", numShards, 0)
-            .addIfNotDefault("validation", validate, true);
+            .add(DisplayData.item("schema", type))
+            .addIfNotNull(DisplayData.item("filePrefix", filenamePrefix))
+            .addIfNotDefault(
+                DisplayData.item("shardNameTemplate", shardTemplate),
+                DEFAULT_SHARD_TEMPLATE)
+            .addIfNotDefault(DisplayData.item("fileSuffix", filenameSuffix), "")
+            .addIfNotDefault(DisplayData.item("numShards", numShards), 0)
+            .addIfNotDefault(DisplayData.item("validation", validate), true);
       }
 
       /**

http://git-wip-us.apache.org/repos/asf/incubator-beam/blob/47c7abca/sdks/java/core/src/main/java/org/apache/beam/sdk/io/BigQueryIO.java
----------------------------------------------------------------------
diff --git a/sdks/java/core/src/main/java/org/apache/beam/sdk/io/BigQueryIO.java b/sdks/java/core/src/main/java/org/apache/beam/sdk/io/BigQueryIO.java
index 1d5b993..4a0bdac 100644
--- a/sdks/java/core/src/main/java/org/apache/beam/sdk/io/BigQueryIO.java
+++ b/sdks/java/core/src/main/java/org/apache/beam/sdk/io/BigQueryIO.java
@@ -522,13 +522,13 @@ public class BigQueryIO {
         super.populateDisplayData(builder);
 
         if (table != null) {
-          builder.add("table", toTableSpec(table));
+          builder.add(DisplayData.item("table", toTableSpec(table)));
         }
 
         builder
-            .addIfNotNull("query", query)
-            .addIfNotNull("flattenResults", flattenResults)
-            .addIfNotDefault("validation", validate, true);
+            .addIfNotNull(DisplayData.item("query", query))
+            .addIfNotNull(DisplayData.item("flattenResults", flattenResults))
+            .addIfNotDefault(DisplayData.item("validation", validate), true);
       }
 
       static {
@@ -1067,17 +1067,17 @@ public class BigQueryIO {
         super.populateDisplayData(builder);
 
         builder
-            .addIfNotNull("table", jsonTableRef)
-            .addIfNotNull("schema", jsonSchema);
+            .addIfNotNull(DisplayData.item("table", jsonTableRef))
+            .addIfNotNull(DisplayData.item("schema", jsonSchema));
 
         if (tableRefFunction != null) {
-          builder.add("tableFn", tableRefFunction.getClass());
+          builder.add(DisplayData.item("tableFn", tableRefFunction.getClass()));
         }
 
         builder
-            .add("createDisposition", createDisposition.toString())
-            .add("writeDisposition", writeDisposition.toString())
-            .addIfNotDefault("validation", validate, true);
+            .add(DisplayData.item("createDisposition", createDisposition.toString()))
+            .add(DisplayData.item("writeDisposition", writeDisposition.toString()))
+            .addIfNotDefault(DisplayData.item("validation", validate), true);
       }
 
       /** Returns the create disposition. */

http://git-wip-us.apache.org/repos/asf/incubator-beam/blob/47c7abca/sdks/java/core/src/main/java/org/apache/beam/sdk/io/BoundedReadFromUnboundedSource.java
----------------------------------------------------------------------
diff --git a/sdks/java/core/src/main/java/org/apache/beam/sdk/io/BoundedReadFromUnboundedSource.java b/sdks/java/core/src/main/java/org/apache/beam/sdk/io/BoundedReadFromUnboundedSource.java
index dc57b91..cf4f02d 100644
--- a/sdks/java/core/src/main/java/org/apache/beam/sdk/io/BoundedReadFromUnboundedSource.java
+++ b/sdks/java/core/src/main/java/org/apache/beam/sdk/io/BoundedReadFromUnboundedSource.java
@@ -113,9 +113,9 @@ class BoundedReadFromUnboundedSource<T> extends PTransform<PInput, PCollection<T
   public void populateDisplayData(DisplayData.Builder builder) {
     // We explicitly do not register base-class data, instead we use the delegate inner source.
     builder
-        .add("source", source.getClass())
-        .addIfNotDefault("maxRecords", maxNumRecords, Long.MAX_VALUE)
-        .addIfNotNull("maxReadTime", maxReadTime)
+        .add(DisplayData.item("source", source.getClass()))
+        .addIfNotDefault(DisplayData.item("maxRecords", maxNumRecords), Long.MAX_VALUE)
+        .addIfNotNull(DisplayData.item("maxReadTime", maxReadTime))
         .include(source);
   }
 

http://git-wip-us.apache.org/repos/asf/incubator-beam/blob/47c7abca/sdks/java/core/src/main/java/org/apache/beam/sdk/io/CompressedSource.java
----------------------------------------------------------------------
diff --git a/sdks/java/core/src/main/java/org/apache/beam/sdk/io/CompressedSource.java b/sdks/java/core/src/main/java/org/apache/beam/sdk/io/CompressedSource.java
index ce21595..370c1e2 100644
--- a/sdks/java/core/src/main/java/org/apache/beam/sdk/io/CompressedSource.java
+++ b/sdks/java/core/src/main/java/org/apache/beam/sdk/io/CompressedSource.java
@@ -326,14 +326,14 @@ public class CompressedSource<T> extends FileBasedSource<T> {
     // We explicitly do not register base-class data, instead we use the delegate inner source.
     builder
         .include(sourceDelegate)
-        .add("source", sourceDelegate.getClass());
+        .add(DisplayData.item("source", sourceDelegate.getClass()));
 
     if (channelFactory instanceof Enum) {
       // GZIP and BZIP are implemented as enums; Enum classes are anonymous, so use the .name()
       // value instead
-      builder.add("compressionMode", ((Enum) channelFactory).name());
+      builder.add(DisplayData.item("compressionMode", ((Enum) channelFactory).name()));
     } else {
-      builder.add("compressionMode", channelFactory.getClass());
+      builder.add(DisplayData.item("compressionMode", channelFactory.getClass()));
     }
   }
 

http://git-wip-us.apache.org/repos/asf/incubator-beam/blob/47c7abca/sdks/java/core/src/main/java/org/apache/beam/sdk/io/CountingInput.java
----------------------------------------------------------------------
diff --git a/sdks/java/core/src/main/java/org/apache/beam/sdk/io/CountingInput.java b/sdks/java/core/src/main/java/org/apache/beam/sdk/io/CountingInput.java
index f6b1256..5a53e4d 100644
--- a/sdks/java/core/src/main/java/org/apache/beam/sdk/io/CountingInput.java
+++ b/sdks/java/core/src/main/java/org/apache/beam/sdk/io/CountingInput.java
@@ -119,7 +119,7 @@ public class CountingInput {
     @Override
     public void populateDisplayData(DisplayData.Builder builder) {
       super.populateDisplayData(builder);
-      builder.add("upTo", numElements);
+      builder.add(DisplayData.item("upTo", numElements));
     }
   }
 
@@ -233,14 +233,14 @@ public class CountingInput {
     public void populateDisplayData(DisplayData.Builder builder) {
       super.populateDisplayData(builder);
 
-      builder.add("timestampFn", timestampFn.getClass());
+      builder.add(DisplayData.item("timestampFn", timestampFn.getClass()));
 
       if (maxReadTime.isPresent()) {
-        builder.add("maxReadTime", maxReadTime.get());
+        builder.add(DisplayData.item("maxReadTime", maxReadTime.get()));
       }
 
       if (maxNumRecords.isPresent()) {
-        builder.add("maxRecords", maxNumRecords.get());
+        builder.add(DisplayData.item("maxRecords", maxNumRecords.get()));
       }
     }
   }

http://git-wip-us.apache.org/repos/asf/incubator-beam/blob/47c7abca/sdks/java/core/src/main/java/org/apache/beam/sdk/io/DatastoreIO.java
----------------------------------------------------------------------
diff --git a/sdks/java/core/src/main/java/org/apache/beam/sdk/io/DatastoreIO.java b/sdks/java/core/src/main/java/org/apache/beam/sdk/io/DatastoreIO.java
index c265659..81c3a39 100644
--- a/sdks/java/core/src/main/java/org/apache/beam/sdk/io/DatastoreIO.java
+++ b/sdks/java/core/src/main/java/org/apache/beam/sdk/io/DatastoreIO.java
@@ -391,12 +391,12 @@ public class DatastoreIO {
     public void populateDisplayData(DisplayData.Builder builder) {
       super.populateDisplayData(builder);
       builder
-          .addIfNotDefault("host", host, DEFAULT_HOST)
-          .addIfNotNull("dataset", datasetId)
-          .addIfNotNull("namespace", namespace);
+          .addIfNotDefault(DisplayData.item("host", host), DEFAULT_HOST)
+          .addIfNotNull(DisplayData.item("dataset", datasetId))
+          .addIfNotNull(DisplayData.item("namespace", namespace));
 
       if (query != null) {
-        builder.add("query", query.toString());
+        builder.add(DisplayData.item("query", query.toString()));
       }
     }
 
@@ -606,8 +606,8 @@ public class DatastoreIO {
     public void populateDisplayData(DisplayData.Builder builder) {
       super.populateDisplayData(builder);
       builder
-          .addIfNotDefault("host", host, DEFAULT_HOST)
-          .addIfNotNull("dataset", datasetId);
+          .addIfNotDefault(DisplayData.item("host", host), DEFAULT_HOST)
+          .addIfNotNull(DisplayData.item("dataset", datasetId));
     }
   }
 

http://git-wip-us.apache.org/repos/asf/incubator-beam/blob/47c7abca/sdks/java/core/src/main/java/org/apache/beam/sdk/io/FileBasedSink.java
----------------------------------------------------------------------
diff --git a/sdks/java/core/src/main/java/org/apache/beam/sdk/io/FileBasedSink.java b/sdks/java/core/src/main/java/org/apache/beam/sdk/io/FileBasedSink.java
index ba3d4ea..10e93f5 100644
--- a/sdks/java/core/src/main/java/org/apache/beam/sdk/io/FileBasedSink.java
+++ b/sdks/java/core/src/main/java/org/apache/beam/sdk/io/FileBasedSink.java
@@ -142,7 +142,7 @@ public abstract class FileBasedSink<T> extends Sink<T> {
 
     String fileNamePattern = String.format("%s%s%s",
         baseOutputFilename, fileNamingTemplate, getFileExtension(extension));
-    builder.add("fileNamePattern", fileNamePattern);
+    builder.add(DisplayData.item("fileNamePattern", fileNamePattern));
   }
 
   /**

http://git-wip-us.apache.org/repos/asf/incubator-beam/blob/47c7abca/sdks/java/core/src/main/java/org/apache/beam/sdk/io/FileBasedSource.java
----------------------------------------------------------------------
diff --git a/sdks/java/core/src/main/java/org/apache/beam/sdk/io/FileBasedSource.java b/sdks/java/core/src/main/java/org/apache/beam/sdk/io/FileBasedSource.java
index bbb2fef..954877f 100644
--- a/sdks/java/core/src/main/java/org/apache/beam/sdk/io/FileBasedSource.java
+++ b/sdks/java/core/src/main/java/org/apache/beam/sdk/io/FileBasedSource.java
@@ -277,7 +277,7 @@ public abstract class FileBasedSource<T> extends OffsetBasedSource<T> {
   @Override
   public void populateDisplayData(DisplayData.Builder builder) {
     super.populateDisplayData(builder);
-    builder.add("filePattern", getFileOrPatternSpec());
+    builder.add(DisplayData.item("filePattern", getFileOrPatternSpec()));
   }
 
   private ListenableFuture<List<? extends FileBasedSource<T>>> createFutureForFileSplit(

http://git-wip-us.apache.org/repos/asf/incubator-beam/blob/47c7abca/sdks/java/core/src/main/java/org/apache/beam/sdk/io/OffsetBasedSource.java
----------------------------------------------------------------------
diff --git a/sdks/java/core/src/main/java/org/apache/beam/sdk/io/OffsetBasedSource.java b/sdks/java/core/src/main/java/org/apache/beam/sdk/io/OffsetBasedSource.java
index 69585a5..126535a 100644
--- a/sdks/java/core/src/main/java/org/apache/beam/sdk/io/OffsetBasedSource.java
+++ b/sdks/java/core/src/main/java/org/apache/beam/sdk/io/OffsetBasedSource.java
@@ -207,9 +207,9 @@ public abstract class OffsetBasedSource<T> extends BoundedSource<T> {
   public void populateDisplayData(DisplayData.Builder builder) {
     super.populateDisplayData(builder);
     builder
-        .add("minBundleSize", minBundleSize)
-        .addIfNotDefault("startOffset", startOffset, 0)
-        .addIfNotDefault("endOffset", endOffset, Long.MAX_VALUE);
+        .add(DisplayData.item("minBundleSize", minBundleSize))
+        .addIfNotDefault(DisplayData.item("startOffset", startOffset), 0L)
+        .addIfNotDefault(DisplayData.item("endOffset", endOffset), Long.MAX_VALUE);
   }
 
   /**

http://git-wip-us.apache.org/repos/asf/incubator-beam/blob/47c7abca/sdks/java/core/src/main/java/org/apache/beam/sdk/io/PubsubIO.java
----------------------------------------------------------------------
diff --git a/sdks/java/core/src/main/java/org/apache/beam/sdk/io/PubsubIO.java b/sdks/java/core/src/main/java/org/apache/beam/sdk/io/PubsubIO.java
index 1b0ec4a..66d1d43 100644
--- a/sdks/java/core/src/main/java/org/apache/beam/sdk/io/PubsubIO.java
+++ b/sdks/java/core/src/main/java/org/apache/beam/sdk/io/PubsubIO.java
@@ -694,17 +694,17 @@ public class PubsubIO {
         super.populateDisplayData(builder);
 
         builder
-            .addIfNotNull("timestampLabel", timestampLabel)
-            .addIfNotNull("idLabel", idLabel)
-            .addIfNotNull("maxReadTime", maxReadTime)
-            .addIfNotDefault("maxNumRecords", maxNumRecords, 0);
+            .addIfNotNull(DisplayData.item("timestampLabel", timestampLabel))
+            .addIfNotNull(DisplayData.item("idLabel", idLabel))
+            .addIfNotNull(DisplayData.item("maxReadTime", maxReadTime))
+            .addIfNotDefault(DisplayData.item("maxNumRecords", maxNumRecords), 0);
 
         if (topic != null) {
-          builder.add("topic", topic.asPath());
+          builder.add(DisplayData.item("topic", topic.asPath()));
         }
 
         if (subscription != null) {
-          builder.add("subscription", subscription.asPath());
+          builder.add(DisplayData.item("subscription", subscription.asPath()));
         }
       }
 
@@ -998,11 +998,11 @@ public class PubsubIO {
         super.populateDisplayData(builder);
 
         builder
-            .addIfNotNull("timestampLabel", timestampLabel)
-            .addIfNotNull("idLabel", idLabel);
+            .addIfNotNull(DisplayData.item("timestampLabel", timestampLabel))
+            .addIfNotNull(DisplayData.item("idLabel", idLabel));
 
         if (topic != null) {
-          builder.add("topic", topic.asPath());
+          builder.add(DisplayData.item("topic", topic.asPath()));
         }
       }
 

http://git-wip-us.apache.org/repos/asf/incubator-beam/blob/47c7abca/sdks/java/core/src/main/java/org/apache/beam/sdk/io/Read.java
----------------------------------------------------------------------
diff --git a/sdks/java/core/src/main/java/org/apache/beam/sdk/io/Read.java b/sdks/java/core/src/main/java/org/apache/beam/sdk/io/Read.java
index 05b70ac..965b14f 100644
--- a/sdks/java/core/src/main/java/org/apache/beam/sdk/io/Read.java
+++ b/sdks/java/core/src/main/java/org/apache/beam/sdk/io/Read.java
@@ -149,7 +149,7 @@ public class Read {
     public void populateDisplayData(DisplayData.Builder builder) {
       super.populateDisplayData(builder);
       builder
-          .add("source", source.getClass())
+          .add(DisplayData.item("source", source.getClass()))
           .include(source);
     }
 
@@ -264,7 +264,7 @@ public class Read {
     public void populateDisplayData(DisplayData.Builder builder) {
       super.populateDisplayData(builder);
       builder
-          .add("source", source.getClass())
+          .add(DisplayData.item("source", source.getClass()))
           .include(source);
     }
   }

http://git-wip-us.apache.org/repos/asf/incubator-beam/blob/47c7abca/sdks/java/core/src/main/java/org/apache/beam/sdk/io/TextIO.java
----------------------------------------------------------------------
diff --git a/sdks/java/core/src/main/java/org/apache/beam/sdk/io/TextIO.java b/sdks/java/core/src/main/java/org/apache/beam/sdk/io/TextIO.java
index 3882ee1..7f69c0a 100644
--- a/sdks/java/core/src/main/java/org/apache/beam/sdk/io/TextIO.java
+++ b/sdks/java/core/src/main/java/org/apache/beam/sdk/io/TextIO.java
@@ -344,9 +344,9 @@ public class TextIO {
         super.populateDisplayData(builder);
 
         builder
-            .add("compressionType", compressionType.toString())
-            .addIfNotDefault("validation", validate, true)
-            .addIfNotNull("filePattern", filepattern);
+            .add(DisplayData.item("compressionType", compressionType.toString()))
+            .addIfNotDefault(DisplayData.item("validation", validate), true)
+            .addIfNotNull(DisplayData.item("filePattern", filepattern));
       }
 
       @Override
@@ -649,11 +649,13 @@ public class TextIO {
         super.populateDisplayData(builder);
 
         builder
-            .addIfNotNull("filePrefix", filenamePrefix)
-            .addIfNotDefault("fileSuffix", filenameSuffix, "")
-            .addIfNotDefault("shardNameTemplate", shardTemplate, DEFAULT_SHARD_TEMPLATE)
-            .addIfNotDefault("validation", validate, true)
-            .addIfNotDefault("numShards", numShards, 0);
+            .addIfNotNull(DisplayData.item("filePrefix", filenamePrefix))
+            .addIfNotDefault(DisplayData.item("fileSuffix", filenameSuffix), "")
+            .addIfNotDefault(
+                DisplayData.item("shardNameTemplate", shardTemplate),
+                DEFAULT_SHARD_TEMPLATE)
+            .addIfNotDefault(DisplayData.item("validation", validate), true)
+            .addIfNotDefault(DisplayData.item("numShards", numShards), 0);
       }
 
       /**

http://git-wip-us.apache.org/repos/asf/incubator-beam/blob/47c7abca/sdks/java/core/src/main/java/org/apache/beam/sdk/io/Write.java
----------------------------------------------------------------------
diff --git a/sdks/java/core/src/main/java/org/apache/beam/sdk/io/Write.java b/sdks/java/core/src/main/java/org/apache/beam/sdk/io/Write.java
index a7d182d..b6743fa 100644
--- a/sdks/java/core/src/main/java/org/apache/beam/sdk/io/Write.java
+++ b/sdks/java/core/src/main/java/org/apache/beam/sdk/io/Write.java
@@ -81,7 +81,7 @@ public class Write {
     public void populateDisplayData(DisplayData.Builder builder) {
       super.populateDisplayData(builder);
       builder
-          .add("sink", sink.getClass())
+          .add(DisplayData.item("sink", sink.getClass()))
           .include(sink);
     }
 

http://git-wip-us.apache.org/repos/asf/incubator-beam/blob/47c7abca/sdks/java/core/src/main/java/org/apache/beam/sdk/io/XmlSink.java
----------------------------------------------------------------------
diff --git a/sdks/java/core/src/main/java/org/apache/beam/sdk/io/XmlSink.java b/sdks/java/core/src/main/java/org/apache/beam/sdk/io/XmlSink.java
index 00819c9..eb7ba38 100644
--- a/sdks/java/core/src/main/java/org/apache/beam/sdk/io/XmlSink.java
+++ b/sdks/java/core/src/main/java/org/apache/beam/sdk/io/XmlSink.java
@@ -227,8 +227,8 @@ public class XmlSink {
     public void populateDisplayData(DisplayData.Builder builder) {
       super.populateDisplayData(builder);
       builder
-          .addIfNotNull("rootElement", rootElementName)
-          .addIfNotNull("recordClass", classToBind);
+          .addIfNotNull(DisplayData.item("rootElement", rootElementName))
+          .addIfNotNull(DisplayData.item("recordClass", classToBind));
     }
   }
 

http://git-wip-us.apache.org/repos/asf/incubator-beam/blob/47c7abca/sdks/java/core/src/main/java/org/apache/beam/sdk/io/XmlSource.java
----------------------------------------------------------------------
diff --git a/sdks/java/core/src/main/java/org/apache/beam/sdk/io/XmlSource.java b/sdks/java/core/src/main/java/org/apache/beam/sdk/io/XmlSource.java
index 89b1032..0a418c8 100644
--- a/sdks/java/core/src/main/java/org/apache/beam/sdk/io/XmlSource.java
+++ b/sdks/java/core/src/main/java/org/apache/beam/sdk/io/XmlSource.java
@@ -222,9 +222,9 @@ public class XmlSource<T> extends FileBasedSource<T> {
   public void populateDisplayData(DisplayData.Builder builder) {
     super.populateDisplayData(builder);
     builder
-        .addIfNotNull("rootElement", rootElement)
-        .addIfNotNull("recordElement", recordElement)
-        .addIfNotNull("recordClass", recordClass);
+        .addIfNotNull(DisplayData.item("rootElement", rootElement))
+        .addIfNotNull(DisplayData.item("recordElement", recordElement))
+        .addIfNotNull(DisplayData.item("recordClass", recordClass));
   }
 
   @Override

http://git-wip-us.apache.org/repos/asf/incubator-beam/blob/47c7abca/sdks/java/core/src/main/java/org/apache/beam/sdk/options/ProxyInvocationHandler.java
----------------------------------------------------------------------
diff --git a/sdks/java/core/src/main/java/org/apache/beam/sdk/options/ProxyInvocationHandler.java b/sdks/java/core/src/main/java/org/apache/beam/sdk/options/ProxyInvocationHandler.java
index a269f4e..745549f 100644
--- a/sdks/java/core/src/main/java/org/apache/beam/sdk/options/ProxyInvocationHandler.java
+++ b/sdks/java/core/src/main/java/org/apache/beam/sdk/options/ProxyInvocationHandler.java
@@ -283,11 +283,11 @@ class ProxyInvocationHandler implements InvocationHandler {
       for (PipelineOptionSpec optionSpec : specs) {
         Class<?> pipelineInterface = optionSpec.getDefiningInterface();
         if (type != null) {
-          builder.add(option.getKey(), type, value)
-              .withNamespace(pipelineInterface);
+          builder.add(DisplayData.item(option.getKey(), type, value)
+              .withNamespace(pipelineInterface));
         } else {
-          builder.add(option.getKey(), value.toString())
-              .withNamespace(pipelineInterface);
+          builder.add(DisplayData.item(option.getKey(), value.toString())
+              .withNamespace(pipelineInterface));
         }
       }
     }
@@ -300,18 +300,18 @@ class ProxyInvocationHandler implements InvocationHandler {
 
       HashSet<PipelineOptionSpec> specs = new HashSet<>(optionsMap.get(jsonOption.getKey()));
       if (specs.isEmpty()) {
-        builder.add(jsonOption.getKey(), jsonOption.getValue().toString())
-          .withNamespace(UnknownPipelineOptions.class);
+        builder.add(DisplayData.item(jsonOption.getKey(), jsonOption.getValue().toString())
+          .withNamespace(UnknownPipelineOptions.class));
       } else {
         for (PipelineOptionSpec spec : specs) {
           Object value = getValueFromJson(jsonOption.getKey(), spec.getGetterMethod());
           DisplayData.Type type = DisplayData.inferType(value);
           if (type != null) {
-            builder.add(jsonOption.getKey(), type, value)
-                .withNamespace(spec.getDefiningInterface());
+            builder.add(DisplayData.item(jsonOption.getKey(), type, value)
+                .withNamespace(spec.getDefiningInterface()));
           } else {
-            builder.add(jsonOption.getKey(), value.toString())
-                .withNamespace(spec.getDefiningInterface());
+            builder.add(DisplayData.item(jsonOption.getKey(), value.toString())
+                .withNamespace(spec.getDefiningInterface()));
           }
         }
       }
@@ -542,7 +542,7 @@ class ProxyInvocationHandler implements InvocationHandler {
         jgen.writeObject(serializableOptions);
 
         List<Map<String, Object>> serializedDisplayData = Lists.newArrayList();
-        for (DisplayData.Item item : DisplayData.from(value).items()) {
+        for (DisplayData.Item<?> item : DisplayData.from(value).items()) {
           @SuppressWarnings("unchecked")
           Map<String, Object> serializedItem = MAPPER.convertValue(item, Map.class);
           serializedDisplayData.add(serializedItem);

http://git-wip-us.apache.org/repos/asf/incubator-beam/blob/47c7abca/sdks/java/core/src/main/java/org/apache/beam/sdk/transforms/ApproximateQuantiles.java
----------------------------------------------------------------------
diff --git a/sdks/java/core/src/main/java/org/apache/beam/sdk/transforms/ApproximateQuantiles.java b/sdks/java/core/src/main/java/org/apache/beam/sdk/transforms/ApproximateQuantiles.java
index dd99b9a..66f7a6a 100644
--- a/sdks/java/core/src/main/java/org/apache/beam/sdk/transforms/ApproximateQuantiles.java
+++ b/sdks/java/core/src/main/java/org/apache/beam/sdk/transforms/ApproximateQuantiles.java
@@ -365,8 +365,8 @@ public class ApproximateQuantiles {
     public void populateDisplayData(DisplayData.Builder builder) {
       super.populateDisplayData(builder);
       builder
-          .add("numQuantiles", numQuantiles)
-          .add("comparer", compareFn.getClass());
+          .add(DisplayData.item("numQuantiles", numQuantiles))
+          .add(DisplayData.item("comparer", compareFn.getClass()));
     }
   }
 

http://git-wip-us.apache.org/repos/asf/incubator-beam/blob/47c7abca/sdks/java/core/src/main/java/org/apache/beam/sdk/transforms/ApproximateUnique.java
----------------------------------------------------------------------
diff --git a/sdks/java/core/src/main/java/org/apache/beam/sdk/transforms/ApproximateUnique.java b/sdks/java/core/src/main/java/org/apache/beam/sdk/transforms/ApproximateUnique.java
index 46bad0c..e4559d4 100644
--- a/sdks/java/core/src/main/java/org/apache/beam/sdk/transforms/ApproximateUnique.java
+++ b/sdks/java/core/src/main/java/org/apache/beam/sdk/transforms/ApproximateUnique.java
@@ -461,7 +461,7 @@ public class ApproximateUnique {
   private static void populateDisplayData(
       DisplayData.Builder builder, long sampleSize, Double maxEstimationError) {
     builder
-        .add("sampleSize", sampleSize)
-        .addIfNotNull("maximumEstimationError", maxEstimationError);
+        .add(DisplayData.item("sampleSize", sampleSize))
+        .addIfNotNull(DisplayData.item("maximumEstimationError", maxEstimationError));
   }
 }

http://git-wip-us.apache.org/repos/asf/incubator-beam/blob/47c7abca/sdks/java/core/src/main/java/org/apache/beam/sdk/transforms/Combine.java
----------------------------------------------------------------------
diff --git a/sdks/java/core/src/main/java/org/apache/beam/sdk/transforms/Combine.java b/sdks/java/core/src/main/java/org/apache/beam/sdk/transforms/Combine.java
index b13b0fc..68fc1cf 100644
--- a/sdks/java/core/src/main/java/org/apache/beam/sdk/transforms/Combine.java
+++ b/sdks/java/core/src/main/java/org/apache/beam/sdk/transforms/Combine.java
@@ -1416,14 +1416,14 @@ public class Combine {
       DisplayData.Builder builder, HasDisplayData fn, ClassForDisplay fnClass) {
     builder
         .include(fn, fnClass)
-        .add("combineFn", fnClass);
+        .add(DisplayData.item("combineFn", fnClass));
   }
 
   private static void populateGlobalDisplayData(
       DisplayData.Builder builder, int fanout, boolean insertDefault) {
     builder
-        .addIfNotDefault("fanout", fanout, 0)
-        .add("emitDefaultOnEmptyInput", insertDefault);
+        .addIfNotDefault(DisplayData.item("fanout", fanout), 0)
+        .add(DisplayData.item("emitDefaultOnEmptyInput", insertDefault));
   }
 
   /**
@@ -1598,7 +1598,7 @@ public class Combine {
     @Override
     public void populateDisplayData(DisplayData.Builder builder) {
       super.populateDisplayData(builder);
-      builder.add("combineFn", combiner.getClass());
+      builder.add(DisplayData.item("combineFn", combiner.getClass()));
     }
 
     private List<V> mergeToSingleton(Iterable<V> values) {
@@ -2088,7 +2088,7 @@ public class Combine {
       super.populateDisplayData(builder);
 
       Combine.populateDisplayData(builder, fn, fnClass);
-      builder.add("fanoutFn", hotKeyFanout.getClass());
+      builder.add(DisplayData.item("fanoutFn", hotKeyFanout.getClass()));
     }
 
     /**

http://git-wip-us.apache.org/repos/asf/incubator-beam/blob/47c7abca/sdks/java/core/src/main/java/org/apache/beam/sdk/transforms/CombineFns.java
----------------------------------------------------------------------
diff --git a/sdks/java/core/src/main/java/org/apache/beam/sdk/transforms/CombineFns.java b/sdks/java/core/src/main/java/org/apache/beam/sdk/transforms/CombineFns.java
index a9500d8..1bf305f 100644
--- a/sdks/java/core/src/main/java/org/apache/beam/sdk/transforms/CombineFns.java
+++ b/sdks/java/core/src/main/java/org/apache/beam/sdk/transforms/CombineFns.java
@@ -1053,7 +1053,7 @@ public class CombineFns {
 
     for (int i = 0; i < combineFns.size(); i++) {
       HasDisplayData combineFn = combineFns.get(i);
-      builder.add("combineFn" + (i + 1), combineFn.getClass());
+      builder.add(DisplayData.item("combineFn" + (i + 1), combineFn.getClass()));
       combineFnMap.put(combineFn.getClass(), combineFn);
     }
 

http://git-wip-us.apache.org/repos/asf/incubator-beam/blob/47c7abca/sdks/java/core/src/main/java/org/apache/beam/sdk/transforms/Filter.java
----------------------------------------------------------------------
diff --git a/sdks/java/core/src/main/java/org/apache/beam/sdk/transforms/Filter.java b/sdks/java/core/src/main/java/org/apache/beam/sdk/transforms/Filter.java
index 0108958..da692b2 100644
--- a/sdks/java/core/src/main/java/org/apache/beam/sdk/transforms/Filter.java
+++ b/sdks/java/core/src/main/java/org/apache/beam/sdk/transforms/Filter.java
@@ -261,6 +261,6 @@ public class Filter<T> extends PTransform<PCollection<T>, PCollection<T>> {
 
   private static void populateDisplayData(
       DisplayData.Builder builder, String predicateDescription) {
-    builder.add("predicate", predicateDescription);
+    builder.add(DisplayData.item("predicate", predicateDescription));
   }
 }

http://git-wip-us.apache.org/repos/asf/incubator-beam/blob/47c7abca/sdks/java/core/src/main/java/org/apache/beam/sdk/transforms/GroupByKey.java
----------------------------------------------------------------------
diff --git a/sdks/java/core/src/main/java/org/apache/beam/sdk/transforms/GroupByKey.java b/sdks/java/core/src/main/java/org/apache/beam/sdk/transforms/GroupByKey.java
index 0e46a2a..21e6ecf 100644
--- a/sdks/java/core/src/main/java/org/apache/beam/sdk/transforms/GroupByKey.java
+++ b/sdks/java/core/src/main/java/org/apache/beam/sdk/transforms/GroupByKey.java
@@ -279,7 +279,7 @@ public class GroupByKey<K, V>
   public void populateDisplayData(DisplayData.Builder builder) {
     super.populateDisplayData(builder);
     if (fewKeys) {
-      builder.add("fewKeys", true);
+      builder.add(DisplayData.item("fewKeys", true));
     }
   }
 

http://git-wip-us.apache.org/repos/asf/incubator-beam/blob/47c7abca/sdks/java/core/src/main/java/org/apache/beam/sdk/transforms/IntraBundleParallelization.java
----------------------------------------------------------------------
diff --git a/sdks/java/core/src/main/java/org/apache/beam/sdk/transforms/IntraBundleParallelization.java b/sdks/java/core/src/main/java/org/apache/beam/sdk/transforms/IntraBundleParallelization.java
index 36149ca..4b3afb4 100644
--- a/sdks/java/core/src/main/java/org/apache/beam/sdk/transforms/IntraBundleParallelization.java
+++ b/sdks/java/core/src/main/java/org/apache/beam/sdk/transforms/IntraBundleParallelization.java
@@ -178,8 +178,8 @@ public class IntraBundleParallelization {
     public void populateDisplayData(DisplayData.Builder builder) {
       super.populateDisplayData(builder);
       builder
-          .add("maxParallelism", maxParallelism)
-          .add("fn", doFn.getClass())
+          .add(DisplayData.item("maxParallelism", maxParallelism))
+          .add(DisplayData.item("fn", doFn.getClass()))
           .include(doFn);
     }
   }

http://git-wip-us.apache.org/repos/asf/incubator-beam/blob/47c7abca/sdks/java/core/src/main/java/org/apache/beam/sdk/transforms/Max.java
----------------------------------------------------------------------
diff --git a/sdks/java/core/src/main/java/org/apache/beam/sdk/transforms/Max.java b/sdks/java/core/src/main/java/org/apache/beam/sdk/transforms/Max.java
index 96900b4..01a190f 100644
--- a/sdks/java/core/src/main/java/org/apache/beam/sdk/transforms/Max.java
+++ b/sdks/java/core/src/main/java/org/apache/beam/sdk/transforms/Max.java
@@ -209,7 +209,7 @@ public class Max {
     @Override
     public void populateDisplayData(DisplayData.Builder builder) {
       super.populateDisplayData(builder);
-      builder.add("comparer", comparator.getClass());
+      builder.add(DisplayData.item("comparer", comparator.getClass()));
     }
   }
 

http://git-wip-us.apache.org/repos/asf/incubator-beam/blob/47c7abca/sdks/java/core/src/main/java/org/apache/beam/sdk/transforms/Min.java
----------------------------------------------------------------------
diff --git a/sdks/java/core/src/main/java/org/apache/beam/sdk/transforms/Min.java b/sdks/java/core/src/main/java/org/apache/beam/sdk/transforms/Min.java
index 7d69c5a..f20d48b 100644
--- a/sdks/java/core/src/main/java/org/apache/beam/sdk/transforms/Min.java
+++ b/sdks/java/core/src/main/java/org/apache/beam/sdk/transforms/Min.java
@@ -209,7 +209,7 @@ public class Min {
     @Override
     public void populateDisplayData(DisplayData.Builder builder) {
       super.populateDisplayData(builder);
-      builder.add("comparer", comparator.getClass());
+      builder.add(DisplayData.item("comparer", comparator.getClass()));
     }
   }
 

http://git-wip-us.apache.org/repos/asf/incubator-beam/blob/47c7abca/sdks/java/core/src/main/java/org/apache/beam/sdk/transforms/ParDo.java
----------------------------------------------------------------------
diff --git a/sdks/java/core/src/main/java/org/apache/beam/sdk/transforms/ParDo.java b/sdks/java/core/src/main/java/org/apache/beam/sdk/transforms/ParDo.java
index 547486d..000a777 100644
--- a/sdks/java/core/src/main/java/org/apache/beam/sdk/transforms/ParDo.java
+++ b/sdks/java/core/src/main/java/org/apache/beam/sdk/transforms/ParDo.java
@@ -1266,7 +1266,7 @@ public class ParDo {
       DisplayData.Builder builder, DoFn<?, ?> fn, Class<?> fnClass) {
     builder
         .include(fn, fnClass)
-        .add("fn", fnClass);
+        .add(DisplayData.item("fn", fnClass));
   }
 
   /**

http://git-wip-us.apache.org/repos/asf/incubator-beam/blob/47c7abca/sdks/java/core/src/main/java/org/apache/beam/sdk/transforms/Partition.java
----------------------------------------------------------------------
diff --git a/sdks/java/core/src/main/java/org/apache/beam/sdk/transforms/Partition.java b/sdks/java/core/src/main/java/org/apache/beam/sdk/transforms/Partition.java
index fbdb9be..44ba2f3 100644
--- a/sdks/java/core/src/main/java/org/apache/beam/sdk/transforms/Partition.java
+++ b/sdks/java/core/src/main/java/org/apache/beam/sdk/transforms/Partition.java
@@ -182,8 +182,8 @@ public class Partition<T> extends PTransform<PCollection<T>, PCollectionList<T>>
     public void populateDisplayData(DisplayData.Builder builder) {
       super.populateDisplayData(builder);
       builder
-          .add("numPartitions", numPartitions)
-          .add("partitionFn", partitionFn.getClass());
+          .add(DisplayData.item("numPartitions", numPartitions))
+          .add(DisplayData.item("partitionFn", partitionFn.getClass()));
     }
   }
 }

http://git-wip-us.apache.org/repos/asf/incubator-beam/blob/47c7abca/sdks/java/core/src/main/java/org/apache/beam/sdk/transforms/Sample.java
----------------------------------------------------------------------
diff --git a/sdks/java/core/src/main/java/org/apache/beam/sdk/transforms/Sample.java b/sdks/java/core/src/main/java/org/apache/beam/sdk/transforms/Sample.java
index 2fba5e3..58188de 100644
--- a/sdks/java/core/src/main/java/org/apache/beam/sdk/transforms/Sample.java
+++ b/sdks/java/core/src/main/java/org/apache/beam/sdk/transforms/Sample.java
@@ -158,7 +158,7 @@ public class Sample {
     @Override
     public void populateDisplayData(DisplayData.Builder builder) {
       super.populateDisplayData(builder);
-      builder.add("sampleSize", limit);
+      builder.add(DisplayData.item("sampleSize", limit));
     }
   }
 
@@ -258,7 +258,7 @@ public class Sample {
     @Override
     public void populateDisplayData(DisplayData.Builder builder) {
       super.populateDisplayData(builder);
-      builder.add("sampleSize", sampleSize);
+      builder.add(DisplayData.item("sampleSize", sampleSize));
     }
   }
 }

http://git-wip-us.apache.org/repos/asf/incubator-beam/blob/47c7abca/sdks/java/core/src/main/java/org/apache/beam/sdk/transforms/Top.java
----------------------------------------------------------------------
diff --git a/sdks/java/core/src/main/java/org/apache/beam/sdk/transforms/Top.java b/sdks/java/core/src/main/java/org/apache/beam/sdk/transforms/Top.java
index 2d38e04..71af081 100644
--- a/sdks/java/core/src/main/java/org/apache/beam/sdk/transforms/Top.java
+++ b/sdks/java/core/src/main/java/org/apache/beam/sdk/transforms/Top.java
@@ -397,8 +397,8 @@ new TopCombineFn<>(count, new Largest<V>()).<K>asKeyedFn())
     public void populateDisplayData(DisplayData.Builder builder) {
       super.populateDisplayData(builder);
       builder
-          .add("count", count)
-          .add("comparer", compareFn.getClass());
+          .add(DisplayData.item("count", count))
+          .add(DisplayData.item("comparer", compareFn.getClass()));
     }
 
     @Override

http://git-wip-us.apache.org/repos/asf/incubator-beam/blob/47c7abca/sdks/java/core/src/main/java/org/apache/beam/sdk/transforms/display/ClassForDisplay.java
----------------------------------------------------------------------
diff --git a/sdks/java/core/src/main/java/org/apache/beam/sdk/transforms/display/ClassForDisplay.java b/sdks/java/core/src/main/java/org/apache/beam/sdk/transforms/display/ClassForDisplay.java
index 3e31c1e..b5142e8 100644
--- a/sdks/java/core/src/main/java/org/apache/beam/sdk/transforms/display/ClassForDisplay.java
+++ b/sdks/java/core/src/main/java/org/apache/beam/sdk/transforms/display/ClassForDisplay.java
@@ -26,7 +26,7 @@ import java.util.Objects;
  * Display data representing a Java class.
  *
  * <p>Java classes can be registered as display data via
- * {@link DisplayData.Builder#add(String, ClassForDisplay)}. {@link ClassForDisplay} is
+ * {@link DisplayData.Builder#item(String, ClassForDisplay)}. {@link ClassForDisplay} is
  * serializable, unlike {@link Class} which can fail to serialize for Java 8 lambda functions.
  */
 public class ClassForDisplay implements Serializable {
@@ -42,14 +42,15 @@ public class ClassForDisplay implements Serializable {
    * Create a {@link ClassForDisplay} instance representing the specified class.
    */
   public static ClassForDisplay of(Class<?> clazz) {
-    return new ClassForDisplay(checkNotNull(clazz));
+    checkNotNull(clazz, "clazz argument cannot be null");
+    return new ClassForDisplay(clazz);
   }
 
   /**
    * Create a {@link ClassForDisplay} from the class of the specified object instance.
    */
   public static ClassForDisplay fromInstance(Object obj) {
-    checkNotNull(obj);
+    checkNotNull(obj, "obj argument instance cannot be null");
     return new ClassForDisplay(obj.getClass());
   }
 

http://git-wip-us.apache.org/repos/asf/incubator-beam/blob/47c7abca/sdks/java/core/src/main/java/org/apache/beam/sdk/transforms/display/DisplayData.java
----------------------------------------------------------------------
diff --git a/sdks/java/core/src/main/java/org/apache/beam/sdk/transforms/display/DisplayData.java b/sdks/java/core/src/main/java/org/apache/beam/sdk/transforms/display/DisplayData.java
index c119057..7666172 100644
--- a/sdks/java/core/src/main/java/org/apache/beam/sdk/transforms/display/DisplayData.java
+++ b/sdks/java/core/src/main/java/org/apache/beam/sdk/transforms/display/DisplayData.java
@@ -17,13 +17,14 @@
  */
 package org.apache.beam.sdk.transforms.display;
 
-import static com.google.common.base.Preconditions.checkArgument;
 import static com.google.common.base.Preconditions.checkNotNull;
 
 import org.apache.beam.sdk.transforms.DoFn;
 import org.apache.beam.sdk.transforms.PTransform;
 import org.apache.beam.sdk.transforms.ParDo;
 
+import com.google.auto.value.AutoValue;
+import com.google.common.base.Preconditions;
 import com.google.common.collect.ImmutableMap;
 import com.google.common.collect.Maps;
 import com.google.common.collect.Sets;
@@ -52,12 +53,12 @@ import java.util.Set;
  * interface.
  */
 public class DisplayData {
-  private static final DisplayData EMPTY = new DisplayData(Maps.<Identifier, Item>newHashMap());
+  private static final DisplayData EMPTY = new DisplayData(Maps.<Identifier, Item<?>>newHashMap());
   private static final DateTimeFormatter TIMESTAMP_FORMATTER = ISODateTimeFormat.dateTime();
 
-  private final ImmutableMap<Identifier, Item> entries;
+  private final ImmutableMap<Identifier, Item<?>> entries;
 
-  private DisplayData(Map<Identifier, Item> entries) {
+  private DisplayData(Map<Identifier, Item<?>> entries) {
     this.entries = ImmutableMap.copyOf(entries);
   }
 
@@ -74,7 +75,7 @@ public class DisplayData {
    * a namespace derived from the component.
    */
   public static DisplayData from(HasDisplayData component) {
-    checkNotNull(component);
+    checkNotNull(component, "component argument cannot be null");
     return InternalBuilder.forRoot(component).build();
   }
 
@@ -89,7 +90,7 @@ public class DisplayData {
    * public void populateDisplayData(DisplayData.Builder builder) {
    *   Optional<DisplayData.Type> type = DisplayData.inferType(foo);
    *   if (type.isPresent()) {
-   *     builder.add("foo", type.get(), foo);
+   *     builder.add(DisplayData.item("foo", type.get(), foo));
    *   }
    * }
    * }
@@ -103,11 +104,11 @@ public class DisplayData {
   }
 
   @JsonValue
-  public Collection<Item> items() {
+  public Collection<Item<?>> items() {
     return entries.values();
   }
 
-  public Map<Identifier, Item> asMap() {
+  public Map<Identifier, Item<?>> asMap() {
     return entries;
   }
 
@@ -130,7 +131,7 @@ public class DisplayData {
   public String toString() {
     StringBuilder builder = new StringBuilder();
     boolean isFirstLine = true;
-    for (Item entry : entries.values()) {
+    for (Item<?> entry : entries.values()) {
       if (isFirstLine) {
         isFirstLine = false;
       } else {
@@ -182,309 +183,79 @@ public class DisplayData {
     Builder include(HasDisplayData subComponent, String namespace);
 
     /**
-     * Register the given string display data. The metadata item will be registered with type
-     * {@link DisplayData.Type#STRING}, and is identified by the specified key and namespace from
-     * the current transform or component.
+     * Register the given display item.
      */
-    ItemBuilder add(String key, String value);
+    Builder add(Item<?> item);
 
     /**
-     * Register the given string display data if the value is not null.
-     *
-     * @see DisplayData.Builder#add(String, String)
-     */
-    ItemBuilder addIfNotNull(String key, @Nullable String value);
-
-    /**
-     * Register the given string display data if the value is different than the specified default.
-     *
-     * @see DisplayData.Builder#add(String, String)
-     */
-    ItemBuilder addIfNotDefault(String key, @Nullable String value, @Nullable String defaultValue);
-
-    /**
-     * Register the given numeric display data. The metadata item will be registered with type
-     * {@link DisplayData.Type#INTEGER}, and is identified by the specified key and namespace from
-     * the current transform or component.
-     */
-    ItemBuilder add(String key, long value);
-
-    /**
-     * Register the given numeric display data if the value is not null.
-     *
-     * @see DisplayData.Builder#add(String, long)
-     */
-    ItemBuilder addIfNotNull(String key, @Nullable Long value);
-
-    /**
-     * Register the given numeric display data if the value is different than the specified default.
-     *
-     * @see DisplayData.Builder#add(String, long)
-     */
-    ItemBuilder addIfNotDefault(String key, long value, long defaultValue);
-
-    /**
-     * Register the given floating point display data. The metadata item will be registered with
-     * type {@link DisplayData.Type#FLOAT}, and is identified by the specified key and namespace
-     * from the current transform or component.
-     */
-    ItemBuilder add(String key, double value);
-
-    /**
-     * Register the given floating point display data if the value is not null.
-     *
-     * @see DisplayData.Builder#add(String, double)
-     */
-    ItemBuilder addIfNotNull(String key, @Nullable Double value);
-
-    /**
-     * Register the given floating point display data if the value is different than the specified
-     * default.
-     *
-     * @see DisplayData.Builder#add(String, double)
-     */
-    ItemBuilder addIfNotDefault(String key, double value, double defaultValue);
-
-    /**
-     * Register the given boolean display data. The metadata item will be registered with
-     * type {@link DisplayData.Type#BOOLEAN}, and is identified by the specified key and namespace
-     * from the current transform or component.
-     */
-    ItemBuilder add(String key, boolean value);
-
-    /**
-     * Register the given boolean display data if the value is not null.
-     *
-     * @see DisplayData.Builder#add(String, boolean)
-     */
-    ItemBuilder addIfNotNull(String key, @Nullable Boolean value);
-
-    /**
-     * Register the given boolean display data if the value is different than the specified default.
-     *
-     * @see DisplayData.Builder#add(String, boolean)
+     * Register the given display item if the value is not null.
      */
-    ItemBuilder addIfNotDefault(String key, boolean value, boolean defaultValue);
+    Builder addIfNotNull(Item<?> item);
 
     /**
-     * Register the given timestamp display data. The metadata item will be registered with type
-     * {@link DisplayData.Type#TIMESTAMP}, and is identified by the specified key and namespace from
-     * the current transform or component.
-     */
-    ItemBuilder add(String key, Instant value);
-
-    /**
-     * Register the given timestamp display data if the value is not null.
-     *
-     * @see DisplayData.Builder#add(String, Instant)
-     */
-    ItemBuilder addIfNotNull(String key, @Nullable Instant value);
-
-    /**
-     * Register the given timestamp display data if the value is different than the specified
-     * default.
-     *
-     * @see DisplayData.Builder#add(String, Instant)
-     */
-    ItemBuilder addIfNotDefault(
-        String key, @Nullable Instant value, @Nullable Instant defaultValue);
-
-    /**
-     * Register the given duration display data. The metadata item will be registered with type
-     * {@link DisplayData.Type#DURATION}, and is identified by the specified key and namespace from
-     * the current transform or component.
-     */
-    ItemBuilder add(String key, Duration value);
-
-    /**
-     * Register the given duration display data if the value is not null.
-     *
-     * @see DisplayData.Builder#add(String, Duration)
-     */
-    ItemBuilder addIfNotNull(String key, @Nullable Duration value);
-
-    /**
-     * Register the given duration display data if the value is different than the specified
-     * default.
-     *
-     * @see DisplayData.Builder#add(String, Duration)
-     */
-    ItemBuilder addIfNotDefault(
-        String key, @Nullable Duration value, @Nullable Duration defaultValue);
-
-    /**
-     * Register the given class display data. The metadata item will be registered with type
-     * {@link DisplayData.Type#JAVA_CLASS}, and is identified by the specified key and namespace
-     * from the current transform or component.
-     */
-    ItemBuilder add(String key, Class<?> value);
-
-    /**
-     * Register the given class display data. The metadata item will be registered with type
-     * {@link DisplayData.Type#JAVA_CLASS}, and is identified by the specified key and namespace
-     * from the current transform or component.
-     */
-    ItemBuilder add(String key, ClassForDisplay value);
-
-    /**
-     * Register the given class display data if the value is not null.
-     *
-     * @see DisplayData.Builder#add(String, Class)
-     */
-    ItemBuilder addIfNotNull(String key, @Nullable Class<?> value);
-
-    /**
-     * Register the given class display data if the value is not null.
-     *
-     * @see DisplayData.Builder#add(String, ClassForDisplay)
-     */
-    ItemBuilder addIfNotNull(String key, @Nullable ClassForDisplay value);
-
-    /**
-     * Register the given class display data if the value is different than the specified default.
-     *
-     * @see DisplayData.Builder#add(String, Class)
+     * Register the given display item if the value is different than the specified default.
      */
-    ItemBuilder addIfNotDefault(
-        String key, @Nullable Class<?> value, @Nullable Class<?> defaultValue);
+    <T> Builder addIfNotDefault(Item<T> item, @Nullable T defaultValue);
+  }
 
-    /**
-     * Register the given class display data if the value is different than the specified default.
-     *
-     * @see DisplayData.Builder#add(String, ClassForDisplay)
-     */
-    ItemBuilder addIfNotDefault(
-        String key, @Nullable ClassForDisplay value, @Nullable ClassForDisplay defaultValue);
   /**
-   * Register the given display data with the specified type.
-   *
-   * <p> The added display data is identified by the specified key and namespace from the current
-   * transform or component.
+   * {@link Item Items} are the unit of display data. Each item is identified by a given key
+   * and namespace from the component the display item belongs to.
    *
-   * @throws ClassCastException if the value cannot be safely cast to the specified type.
-   *
-   * @see DisplayData#inferType(Object)
+   * <p>{@link Item Items} are registered via {@link DisplayData.Builder#add}
+   * within {@link HasDisplayData#populateDisplayData} implementations.
    */
-    ItemBuilder add(String key, Type type, Object value);
-  }
+  @AutoValue
+  public abstract static class Item<T> {
 
-  /**
-   * Utility to append optional fields to display data, or register additional display data
-   * items.
-   */
-  public interface ItemBuilder extends Builder {
     /**
-     * Add a human-readable label to describe the most-recently added metadata field.
-     * A label is optional; if unspecified, UIs should display the metadata key to identify the
-     * display item.
-     *
-     * <p>Specifying a null value will clear the label if it was previously defined.
-     */
-    ItemBuilder withLabel(@Nullable String label);
-
-    /**
-     * Add a link URL to the most-recently added display data. A link URL is optional and
-     * can be provided to point the reader to additional details about the metadata.
-     *
-     * <p>Specifying a null value will clear the URL if it was previously defined.
-     */
-    ItemBuilder withLinkUrl(@Nullable String url);
-
-    /**
-     * Adds an explicit namespace to the most-recently added display data. The namespace
-     * and key uniquely identify the display data.
-     *
-     * <p>Leaving the namespace unspecified will default to the registering instance's class.
+     * The namespace for the display item. The namespace defaults to the component which
+     * the display item belongs to.
      */
-    ItemBuilder withNamespace(Class<?> namespace);
+    @Nullable
+    @JsonGetter("namespace")
+    public abstract String getNamespace();
 
     /**
-     * Adds an explicit namespace to the most-recently added display data. The namespace
-     * and key uniquely identify the display data.
-     *
-     * <p>Leaving the namespace unspecified will default to the registering instance's class.
+     * The key for the display item. Each display item is created with a key and value
+     * via {@link DisplayData#item).
      */
-    ItemBuilder withNamespace(ClassForDisplay namespace);
-  }
-
-  /**
-   * A display data item. DisplayData items are registered via {@link Builder#add} within
-   * {@link HasDisplayData#populateDisplayData} implementations. Each metadata item is uniquely
-   * identified by the specified key and namespace generated from the registering component's
-   * class name.
-   */
-  public static class Item {
-    private final String key;
-    private final String ns;
-    private final Type type;
-    private final Object value;
-    private final Object shortValue;
-    private final String label;
-    private final String url;
-
-    private static Item create(String nsClass, String key, Type type, Object value) {
-      FormattedItemValue formatted = type.format(value);
-      return new Item(
-          nsClass, key, type, formatted.getLongValue(), formatted.getShortValue(), null, null);
-    }
-
-    private Item(
-        String namespace,
-        String key,
-        Type type,
-        Object value,
-        Object shortValue,
-        String url,
-        String label) {
-      this.ns = namespace;
-      this.key = key;
-      this.type = type;
-      this.value = value;
-      this.shortValue = shortValue;
-      this.url = url;
-      this.label = label;
-    }
-
-    @JsonGetter("namespace")
-    public String getNamespace() {
-      return ns;
-    }
-
     @JsonGetter("key")
-    public String getKey() {
-      return key;
-    }
+    public abstract String getKey();
 
     /**
      * Retrieve the {@link DisplayData.Type} of display data. All metadata conforms to a
      * predefined set of allowed types.
      */
     @JsonGetter("type")
-    public Type getType() {
-      return type;
-    }
+    public abstract Type getType();
 
     /**
-     * Retrieve the value of the metadata item.
+     * Retrieve the value of the display item. The value is translated from the input to
+     * {@link DisplayData#item} into a format suitable for display. Translation is based on the
+     * item's {@link #getType() type}.
+     *
+     * <p>The value will only be {@literal null} if the input value during creation was null.
      */
     @JsonGetter("value")
-    public Object getValue() {
-      return value;
-    }
+    @Nullable
+    public abstract Object getValue();
 
     /**
-     * Return the optional short value for an item. Types may provide a short-value to displayed
-     * instead of or in addition to the full {@link Item#value}.
+     * Return the optional short value for an item, or null if none is provided.
      *
-     * <p>Some display data types will not provide a short value, in which case the return value
-     * will be null.
+     * <p>The short value is an alternative display representation for items having a long display
+     * value. For example, the {@link #getValue() value} for {@link Type#JAVA_CLASS} items contains
+     * the full class name with package, while the short value contains just the class name.
+     *
+     * A {@link #getValue() value} will be provided for each display item, and some types may also
+     * provide a short-value. If a short value is provided, display data consumers may
+     * choose to display it instead of or in addition to the {@link #getValue() value}.
      */
     @JsonGetter("shortValue")
     @JsonInclude(JsonInclude.Include.NON_NULL)
     @Nullable
-    public Object getShortValue() {
-      return shortValue;
-    }
+    public abstract Object getShortValue();
 
     /**
      * Retrieve the optional label for an item. The label is a human-readable description of what
@@ -495,9 +266,7 @@ public class DisplayData {
     @JsonGetter("label")
     @JsonInclude(JsonInclude.Include.NON_NULL)
     @Nullable
-    public String getLabel() {
-      return label;
-    }
+    public abstract String getLabel();
 
     /**
      * Retrieve the optional link URL for an item. The URL points to an address where the reader
@@ -508,55 +277,89 @@ public class DisplayData {
     @JsonGetter("linkUrl")
     @JsonInclude(JsonInclude.Include.NON_NULL)
     @Nullable
-    public String getLinkUrl() {
-      return url;
+    public abstract String getLinkUrl();
+
+    private static <T> Item<T> create(String key, Type type, @Nullable T value) {
+      FormattedItemValue formatted = type.safeFormat(value);
+      return of(null, key, type, formatted.getLongValue(), formatted.getShortValue(), null, null);
     }
 
-    @Override
-    public String toString() {
-      return String.format("%s:%s=%s", ns, key, value);
+    /**
+     * Set the item {@link Item#getNamespace() namespace} from the given {@link Class}.
+     *
+     * <p>This method does not alter the current instance, but instead returns a new {@link Item}
+     * with the namespace set.
+     */
+    public Item<T> withNamespace(Class<?> namespace) {
+      checkNotNull(namespace, "namespace argument cannot be null");
+      return withNamespace(ClassForDisplay.of(namespace));
     }
 
-    @Override
-    public boolean equals(Object obj) {
-      if (obj instanceof Item) {
-        Item that = (Item) obj;
-        return Objects.equals(this.ns, that.ns)
-            && Objects.equals(this.key, that.key)
-            && Objects.equals(this.type, that.type)
-            && Objects.equals(this.value, that.value)
-            && Objects.equals(this.shortValue, that.shortValue)
-            && Objects.equals(this.label, that.label)
-            && Objects.equals(this.url, that.url);
-      }
+    /** @see #withNamespace(Class) */
+    private Item<T> withNamespace(ClassForDisplay namespace) {
+      checkNotNull(namespace, "namesapce argument cannot be null");
+      return withNamespace(namespaceOf(namespace));
+    }
 
-      return false;
+    /** @see #withNamespace(Class) */
+    public Item<T> withNamespace(String namespace) {
+      checkNotNull(namespace, "namespace argument cannot be null");
+      return of(
+          namespace, getKey(), getType(), getValue(), getShortValue(), getLabel(), getLinkUrl());
     }
 
-    @Override
-    public int hashCode() {
-      return Objects.hash(
-          this.ns,
-          this.key,
-          this.type,
-          this.value,
-          this.shortValue,
-          this.label,
-          this.url);
+    /**
+     * Set the item {@link Item#getLabel() label}.
+     *
+     * <p>Specifying a null value will clear the label if it was previously defined.
+     *
+     * <p>This method does not alter the current instance, but instead returns a new {@link Item}
+     * with the label set.
+     */
+    public Item<T> withLabel(String label) {
+      return of(
+          getNamespace(), getKey(), getType(), getValue(), getShortValue(), label, getLinkUrl());
+    }
+
+    /**
+     * Set the item {@link Item#getLinkUrl() link url}.
+     *
+     * <p>Specifying a null value will clear the link url if it was previously defined.
+     *
+     * <p>This method does not alter the current instance, but instead returns a new {@link Item}
+     * with the link url set.
+     */
+    public Item<T> withLinkUrl(String url) {
+      return of(getNamespace(), getKey(), getType(), getValue(), getShortValue(), getLabel(), url);
     }
 
-    private Item withLabel(String label) {
-      return new Item(this.ns, this.key, this.type, this.value, this.shortValue, this.url, label);
+    /**
+     * Creates a similar item to the current instance but with the specified value.
+     *
+     * <p>This should only be used internally. It is useful to compare the value of a
+     * {@link DisplayData.Item} to the value derived from a specified input.
+     */
+    private Item<T> withValue(Object value) {
+      FormattedItemValue formatted = getType().safeFormat(value);
+      return of(getNamespace(), getKey(), getType(), formatted.getLongValue(),
+          formatted.getShortValue(), getLabel(), getLinkUrl());
     }
 
-    private Item withUrl(String url) {
-      return new Item(this.ns, this.key, this.type, this.value, this.shortValue, url, this.label);
+    private static <T> Item<T> of(
+        @Nullable String namespace,
+        String key,
+        Type type,
+        @Nullable Object value,
+        @Nullable Object shortValue,
+        @Nullable String label,
+        @Nullable String linkUrl) {
+      return new AutoValue_DisplayData_Item<>(
+          namespace, key, type, value, shortValue, label, linkUrl);
     }
 
-    private Item withNamespace(ClassForDisplay nsClass) {
-      String namespace = namespaceOf(nsClass);
-      return new Item(
-          namespace, this.key, this.type, this.value, this.shortValue, this.url, this.label);
+    @Override
+    public String toString() {
+      return String.format("%s:%s=%s", getNamespace(), getKey(), getValue());
     }
   }
 
@@ -696,6 +499,20 @@ public class DisplayData {
      */
     abstract FormattedItemValue format(Object value);
 
+    /**
+     * Safe version of {@link Type#format(Object)}, which checks for null input value and if so
+     * returns a {@link FormattedItemValue} with null value properties.
+     *
+     * @see #format(Object)
+     */
+    FormattedItemValue safeFormat(@Nullable Object value) {
+      if (value == null) {
+        return FormattedItemValue.NULL_VALUES;
+      }
+
+      return format(value);
+    }
+
     @Nullable
     private static Type tryInferFrom(@Nullable Object value) {
       if (value instanceof Integer || value instanceof Long) {
@@ -719,6 +536,11 @@ public class DisplayData {
   }
 
   static class FormattedItemValue {
+    /**
+     * Default instance which contains null values.
+     */
+    private static final FormattedItemValue NULL_VALUES = new FormattedItemValue(null);
+
     private final Object shortValue;
     private final Object longValue;
 
@@ -740,15 +562,12 @@ public class DisplayData {
     }
   }
 
-  private static class InternalBuilder implements ItemBuilder {
-    private final Map<Identifier, Item> entries;
+  private static class InternalBuilder implements Builder {
+    private final Map<Identifier, Item<?>> entries;
     private final Set<Object> visited;
 
     private String latestNs;
 
-    @Nullable
-    private Item latestItem;
-
     private InternalBuilder() {
       this.entries = Maps.newHashMap();
       this.visited = Sets.newIdentityHashSet();
@@ -762,28 +581,27 @@ public class DisplayData {
 
     @Override
     public Builder include(HasDisplayData subComponent) {
-      checkNotNull(subComponent);
+      checkNotNull(subComponent, "subComponent argument cannot be null");
       return include(subComponent, subComponent.getClass());
     }
 
     @Override
     public Builder include(HasDisplayData subComponent, Class<?> namespace) {
-      checkNotNull(namespace);
+      checkNotNull(namespace, "Input namespace override cannot be null");
       return include(subComponent, ClassForDisplay.of(namespace));
     }
 
     @Override
     public Builder include(HasDisplayData subComponent, ClassForDisplay namespace) {
-      checkNotNull(namespace);
+      checkNotNull(namespace, "Input namespace override cannot be null");
       return include(subComponent, namespaceOf(namespace));
     }
 
     @Override
     public Builder include(HasDisplayData subComponent, String namespace) {
-      checkNotNull(subComponent);
-      checkNotNull(namespace);
+      checkNotNull(subComponent, "subComponent argument cannot be null");
+      checkNotNull(namespace, "Input namespace override cannot be null");
 
-      commitLatest();
       boolean newComponent = visited.add(subComponent);
       if (newComponent) {
         String prevNs = this.latestNs;
@@ -796,202 +614,133 @@ public class DisplayData {
     }
 
     @Override
-    public ItemBuilder add(String key, String value) {
-      checkNotNull(value);
-      return addItemIf(true, key, Type.STRING, value);
-    }
-
-    @Override
-    public ItemBuilder addIfNotNull(String key, @Nullable String value) {
-      return addItemIf(value != null, key, Type.STRING, value);
-    }
-
-    @Override
-    public ItemBuilder addIfNotDefault(
-        String key, @Nullable String value, @Nullable String defaultValue) {
-      return addItemIf(!Objects.equals(value, defaultValue), key, Type.STRING, value);
-    }
-
-    @Override
-    public ItemBuilder add(String key, long value) {
-      return addItemIf(true, key, Type.INTEGER, value);
-    }
-
-    @Override
-    public ItemBuilder addIfNotNull(String key, @Nullable Long value) {
-      return addItemIf(value != null, key, Type.INTEGER, value);
-    }
-
-    @Override
-    public ItemBuilder addIfNotDefault(String key, long value, long defaultValue) {
-      return addItemIf(!Objects.equals(value, defaultValue), key, Type.INTEGER, value);
-    }
-
-    @Override
-    public ItemBuilder add(String key, double value) {
-      return addItemIf(true, key, Type.FLOAT, value);
-    }
-
-    @Override
-    public ItemBuilder addIfNotNull(String key, @Nullable Double value) {
-      return addItemIf(value != null, key, Type.FLOAT, value);
-    }
-
-    @Override
-    public ItemBuilder addIfNotDefault(String key, double value, double defaultValue) {
-      return addItemIf(!Objects.equals(value, defaultValue), key, Type.FLOAT, value);
-    }
-
-    @Override
-    public ItemBuilder add(String key, boolean value) {
-      return addItemIf(true, key, Type.BOOLEAN, value);
-    }
-
-    @Override
-    public ItemBuilder addIfNotNull(String key, @Nullable Boolean value) {
-      return addItemIf(value != null, key, Type.BOOLEAN, value);
-    }
-
-    @Override
-    public ItemBuilder addIfNotDefault(String key, boolean value, boolean defaultValue) {
-      return addItemIf(!Objects.equals(value, defaultValue), key, Type.BOOLEAN, value);
-    }
-
-    @Override
-    public ItemBuilder add(String key, Instant value) {
-      return addItemIf(true, key, Type.TIMESTAMP, value);
-    }
-
-    @Override
-    public ItemBuilder addIfNotNull(String key, @Nullable Instant value) {
-      return addItemIf(value != null, key, Type.TIMESTAMP, value);
-    }
-
-    @Override
-    public ItemBuilder addIfNotDefault(
-        String key, @Nullable Instant value, @Nullable Instant defaultValue) {
-      return addItemIf(!Objects.equals(value, defaultValue), key, Type.TIMESTAMP, value);
-    }
-
-    @Override
-    public ItemBuilder add(String key, Duration value) {
-      return addItemIf(true, key, Type.DURATION, value);
-    }
-
-    @Override
-    public ItemBuilder addIfNotNull(String key, @Nullable Duration value) {
-      return addItemIf(value != null, key, Type.DURATION, value);
-    }
-
-    @Override
-    public ItemBuilder addIfNotDefault(
-        String key, @Nullable Duration value, @Nullable Duration defaultValue) {
-      return addItemIf(!Objects.equals(value, defaultValue), key, Type.DURATION, value);
+    public Builder add(Item<?> item) {
+      checkNotNull(item, "Input display item cannot be null");
+      return addItemIf(true, item);
     }
 
     @Override
-    public ItemBuilder add(String key, Class<?> value) {
-      return addItemIf(true, key, Type.JAVA_CLASS, value);
+    public Builder addIfNotNull(Item<?> item) {
+      checkNotNull(item, "Input display item cannot be null");
+      return addItemIf(item.getValue() != null, item);
     }
 
     @Override
-    public ItemBuilder add(String key, ClassForDisplay value) {
-      checkNotNull(value);
-      return addItemIf(true, key, Type.JAVA_CLASS, value);
+    public <T> Builder addIfNotDefault(Item<T> item, @Nullable T defaultValue) {
+      checkNotNull(item, "Input display item cannot be null");
+      Item<T> defaultItem = item.withValue(defaultValue);
+      return addItemIf(!Objects.equals(item, defaultItem), item);
     }
 
-    @Override
-    public ItemBuilder addIfNotNull(String key, @Nullable Class<?> value) {
-      return addItemIf(value != null, key, Type.JAVA_CLASS, value);
-    }
+    private Builder addItemIf(boolean condition, Item<?> item) {
+      if (!condition) {
+        return this;
+      }
 
-    @Override
-    public ItemBuilder addIfNotNull(String key, @Nullable ClassForDisplay value) {
-      return addItemIf(value != null, key, Type.JAVA_CLASS, value);
-    }
+      checkNotNull(item, "Input display item cannot be null");
+      checkNotNull(item.getValue(), "Input display value cannot be null");
+      if (item.getNamespace() == null) {
+        item = item.withNamespace(latestNs);
+      }
 
-    @Override
-    public ItemBuilder addIfNotDefault(
-        String key, @Nullable Class<?> value, @Nullable Class<?> defaultValue) {
-      return addItemIf(!Objects.equals(value, defaultValue), key, Type.JAVA_CLASS, value);
-    }
+      Identifier id = Identifier.of(item.getNamespace(), item.getKey());
+      Preconditions.checkArgument(!entries.containsKey(id),
+          "Display data key (%s) is not unique within the specified namespace (%s).",
+          item.getKey(), item.getNamespace());
 
-    @Override
-    public ItemBuilder addIfNotDefault(
-        String key, @Nullable ClassForDisplay value, @Nullable ClassForDisplay defaultValue) {
-      return addItemIf(!Objects.equals(value, defaultValue), key, Type.JAVA_CLASS, value);
+      entries.put(id, item);
+      return this;
     }
 
-    @Override
-    public ItemBuilder add(String key, Type type, Object value) {
-      checkNotNull(type);
-      return addItemIf(true, key, type, value);
+    private DisplayData build() {
+      return new DisplayData(this.entries);
     }
+  }
 
-    private ItemBuilder addItemIf(boolean condition, String key, Type type, Object value) {
-      checkNotNull(key, "Display data keys cannot be null or empty.");
-      checkArgument(!key.isEmpty(), "Display data keys cannot be null or empty.");
-      commitLatest();
-
-      if (condition) {
-        checkNotNull(value, "Display data values cannot be null. Key: [%s]", key);
-        latestItem = Item.create(latestNs, key, type, value);
-      }
-
-      return this;
-    }
+  /**
+   * Create a display item for the specified key and string value.
+   */
+  public static Item<String> item(String key, @Nullable String value) {
+    return item(key, Type.STRING, value);
+  }
 
-    private void commitLatest() {
-      if (latestItem == null) {
-        return;
-      }
+  /**
+   * Create a display item for the specified key and integer value.
+   */
+  public static Item<Integer> item(String key, @Nullable Integer value) {
+    return item(key, Type.INTEGER, value);
+  }
 
-      Identifier id = Identifier.of(latestItem.getNamespace(), latestItem.getKey());
-      if (entries.containsKey(id)) {
-        throw new IllegalArgumentException("DisplayData key already exists. All display data "
-          + "for a component must be registered with a unique key.\nKey: " + id);
-      }
+  /**
+   * Create a display item for the specified key and integer value.
+   */
+  public static Item<Long> item(String key, @Nullable Long value) {
+    return item(key, Type.INTEGER, value);
+  }
 
-      entries.put(id, latestItem);
-      latestItem = null;
-    }
+  /**
+   * Create a display item for the specified key and floating point value.
+   */
+  public static Item<Float> item(String key, @Nullable Float value) {
+    return item(key, Type.FLOAT, value);
+  }
 
-    @Override
-    public ItemBuilder withLabel(@Nullable String label) {
-      if (latestItem != null) {
-        latestItem = latestItem.withLabel(label);
-      }
+  /**
+   * Create a display item for the specified key and floating point value.
+   */
+  public static Item<Double> item(String key, @Nullable Double value) {
+    return item(key, Type.FLOAT, value);
+  }
 
-      return this;
-    }
+  /**
+   * Create a display item for the specified key and boolean value.
+   */
+  public static Item<Boolean> item(String key, @Nullable Boolean value) {
+    return item(key, Type.BOOLEAN, value);
+  }
 
-    @Override
-    public ItemBuilder withLinkUrl(@Nullable String url) {
-      if (latestItem != null) {
-        latestItem = latestItem.withUrl(url);
-      }
+  /**
+   * Create a display item for the specified key and timestamp value.
+   */
+  public static Item<Instant> item(String key, @Nullable Instant value) {
+    return item(key, Type.TIMESTAMP, value);
+  }
 
-      return this;
-    }
+  /**
+   * Create a display item for the specified key and duration value.
+   */
+  public static Item<Duration> item(String key, @Nullable Duration value) {
+    return item(key, Type.DURATION, value);
+  }
 
-    @Override
-    public ItemBuilder withNamespace(Class<?> namespace) {
-      checkNotNull(namespace);
-      return withNamespace(ClassForDisplay.of(namespace));
-    }
+  /**
+   * Create a display item for the specified key and class value.
+   */
+  public static <T> Item<Class<T>> item(String key, @Nullable Class<T> value) {
+    return item(key, Type.JAVA_CLASS, value);
+  }
 
-    @Override
-    public ItemBuilder withNamespace(ClassForDisplay namespace) {
-      if (latestItem != null) {
-        latestItem = latestItem.withNamespace(namespace);
-      }
+  /**
+   * Create a display item for the specified key and class value.
+   */
+  public static Item<ClassForDisplay> item(String key, @Nullable ClassForDisplay value) {
+    return item(key, Type.JAVA_CLASS, value);
+  }
 
-      return this;
-    }
+  /**
+   * Create a display item for the specified key, type, and value. This method should be used
+   * if the type of the input value can only be determined at runtime. Otherwise,
+   * {@link HasDisplayData} implementors should call one of the typed factory methods, such as
+   * {@link #item(String, String)} or {@link #item(String, Integer)}.
+   *
+   * @throws ClassCastException if the value cannot be formatted as the given type.
+   *
+   *  @see Type#inferType(Object)
+   */
+  public static <T> Item<T> item(String key, Type type, @Nullable T value) {
+    checkNotNull(key, "key argument cannot be null");
+    checkNotNull(type, "type argument cannot be null");
 
-    private DisplayData build() {
-      commitLatest();
-      return new DisplayData(this.entries);
-    }
+    return Item.create(key, type, value);
   }
 }

http://git-wip-us.apache.org/repos/asf/incubator-beam/blob/47c7abca/sdks/java/core/src/main/java/org/apache/beam/sdk/transforms/display/HasDisplayData.java
----------------------------------------------------------------------
diff --git a/sdks/java/core/src/main/java/org/apache/beam/sdk/transforms/display/HasDisplayData.java b/sdks/java/core/src/main/java/org/apache/beam/sdk/transforms/display/HasDisplayData.java
index b264a14..d74944e 100644
--- a/sdks/java/core/src/main/java/org/apache/beam/sdk/transforms/display/HasDisplayData.java
+++ b/sdks/java/core/src/main/java/org/apache/beam/sdk/transforms/display/HasDisplayData.java
@@ -39,12 +39,12 @@ public interface HasDisplayData {
    * public void populateDisplayData(DisplayData.Builder builder) {
    *  builder
    *     .include(subComponent)
-   *     .add("minFilter", 42)
-   *     .addIfNotDefault("useTransactions", this.txn, false)
-   *     .add("topic", "projects/myproject/topics/mytopic")
-   *       .withLabel("Pub/Sub Topic")
-   *     .add("serviceInstance", "myservice.com/fizzbang")
-   *       .withLinkUrl("http://www.myservice.com/fizzbang");
+   *     .add(DisplayData.item("minFilter", 42))
+   *     .addIfNotDefault(DisplayData.item("useTransactions", this.txn), false)
+   *     .add(DisplayData.item("topic", "projects/myproject/topics/mytopic")
+   *       .withLabel("Pub/Sub Topic"))
+   *     .add(DisplayData.item("serviceInstance", "myservice.com/fizzbang")
+   *       .withLinkUrl("http://www.myservice.com/fizzbang"));
    * }
    * }
    * </pre>

http://git-wip-us.apache.org/repos/asf/incubator-beam/blob/47c7abca/sdks/java/core/src/main/java/org/apache/beam/sdk/transforms/windowing/CalendarWindows.java
----------------------------------------------------------------------
diff --git a/sdks/java/core/src/main/java/org/apache/beam/sdk/transforms/windowing/CalendarWindows.java b/sdks/java/core/src/main/java/org/apache/beam/sdk/transforms/windowing/CalendarWindows.java
index 3084059..490fbd1 100644
--- a/sdks/java/core/src/main/java/org/apache/beam/sdk/transforms/windowing/CalendarWindows.java
+++ b/sdks/java/core/src/main/java/org/apache/beam/sdk/transforms/windowing/CalendarWindows.java
@@ -150,8 +150,9 @@ public class CalendarWindows {
       super.populateDisplayData(builder);
 
       builder
-          .add("numDays", number)
-          .addIfNotDefault("startDate", new DateTime(startDate, timeZone).toInstant(),
+          .add(DisplayData.item("numDays", number))
+          .addIfNotDefault(
+              DisplayData.item("startDate", new DateTime(startDate, timeZone).toInstant()),
               new DateTime(DEFAULT_START_DATE, DateTimeZone.UTC).toInstant());
     }
 
@@ -247,8 +248,9 @@ public class CalendarWindows {
       super.populateDisplayData(builder);
 
       builder
-          .add("numMonths", number)
-          .addIfNotDefault("startDate", new DateTime(startDate, timeZone).toInstant(),
+          .add(DisplayData.item("numMonths", number))
+          .addIfNotDefault(
+            DisplayData.item("startDate", new DateTime(startDate, timeZone).toInstant()),
             new DateTime(DEFAULT_START_DATE, DateTimeZone.UTC).toInstant());
     }
 
@@ -353,8 +355,9 @@ public class CalendarWindows {
       super.populateDisplayData(builder);
 
       builder
-          .add("numYears", number)
-          .addIfNotDefault("startDate", new DateTime(startDate, timeZone).toInstant(),
+          .add(DisplayData.item("numYears", number))
+          .addIfNotDefault(
+              DisplayData.item("startDate", new DateTime(startDate, timeZone).toInstant()),
               new DateTime(DEFAULT_START_DATE, DateTimeZone.UTC).toInstant());
     }
 

http://git-wip-us.apache.org/repos/asf/incubator-beam/blob/47c7abca/sdks/java/core/src/main/java/org/apache/beam/sdk/transforms/windowing/FixedWindows.java
----------------------------------------------------------------------
diff --git a/sdks/java/core/src/main/java/org/apache/beam/sdk/transforms/windowing/FixedWindows.java b/sdks/java/core/src/main/java/org/apache/beam/sdk/transforms/windowing/FixedWindows.java
index fdffebe..322259c 100644
--- a/sdks/java/core/src/main/java/org/apache/beam/sdk/transforms/windowing/FixedWindows.java
+++ b/sdks/java/core/src/main/java/org/apache/beam/sdk/transforms/windowing/FixedWindows.java
@@ -87,8 +87,8 @@ public class FixedWindows extends PartitioningWindowFn<Object, IntervalWindow> {
   public void populateDisplayData(DisplayData.Builder builder) {
     super.populateDisplayData(builder);
     builder
-        .add("size", size)
-        .addIfNotDefault("offset", offset, Duration.ZERO);
+        .add(DisplayData.item("size", size))
+        .addIfNotDefault(DisplayData.item("offset", offset), Duration.ZERO);
   }
 
   @Override

http://git-wip-us.apache.org/repos/asf/incubator-beam/blob/47c7abca/sdks/java/core/src/main/java/org/apache/beam/sdk/transforms/windowing/Sessions.java
----------------------------------------------------------------------
diff --git a/sdks/java/core/src/main/java/org/apache/beam/sdk/transforms/windowing/Sessions.java b/sdks/java/core/src/main/java/org/apache/beam/sdk/transforms/windowing/Sessions.java
index 7010256..8e8a005 100644
--- a/sdks/java/core/src/main/java/org/apache/beam/sdk/transforms/windowing/Sessions.java
+++ b/sdks/java/core/src/main/java/org/apache/beam/sdk/transforms/windowing/Sessions.java
@@ -101,7 +101,7 @@ public class Sessions extends WindowFn<Object, IntervalWindow> {
   @Override
   public void populateDisplayData(DisplayData.Builder builder) {
     super.populateDisplayData(builder);
-    builder.add("gapDuration", gapDuration);
+    builder.add(DisplayData.item("gapDuration", gapDuration));
   }
 
   @Override

http://git-wip-us.apache.org/repos/asf/incubator-beam/blob/47c7abca/sdks/java/core/src/main/java/org/apache/beam/sdk/transforms/windowing/SlidingWindows.java
----------------------------------------------------------------------
diff --git a/sdks/java/core/src/main/java/org/apache/beam/sdk/transforms/windowing/SlidingWindows.java b/sdks/java/core/src/main/java/org/apache/beam/sdk/transforms/windowing/SlidingWindows.java
index bbbedad..4153e21 100644
--- a/sdks/java/core/src/main/java/org/apache/beam/sdk/transforms/windowing/SlidingWindows.java
+++ b/sdks/java/core/src/main/java/org/apache/beam/sdk/transforms/windowing/SlidingWindows.java
@@ -144,9 +144,9 @@ public class SlidingWindows extends NonMergingWindowFn<Object, IntervalWindow> {
   public void populateDisplayData(DisplayData.Builder builder) {
     super.populateDisplayData(builder);
     builder
-        .add("size", size)
-        .add("period", period)
-        .add("offset", offset);
+        .add(DisplayData.item("size", size))
+        .add(DisplayData.item("period", period))
+        .add(DisplayData.item("offset", offset));
   }
 
   /**

http://git-wip-us.apache.org/repos/asf/incubator-beam/blob/47c7abca/sdks/java/core/src/main/java/org/apache/beam/sdk/transforms/windowing/Window.java
----------------------------------------------------------------------
diff --git a/sdks/java/core/src/main/java/org/apache/beam/sdk/transforms/windowing/Window.java b/sdks/java/core/src/main/java/org/apache/beam/sdk/transforms/windowing/Window.java
index b751bec..e9b3437 100644
--- a/sdks/java/core/src/main/java/org/apache/beam/sdk/transforms/windowing/Window.java
+++ b/sdks/java/core/src/main/java/org/apache/beam/sdk/transforms/windowing/Window.java
@@ -600,24 +600,24 @@ public class Window {
     public void populateDisplayData(DisplayData.Builder builder) {
       super.populateDisplayData(builder);
       builder
-          .add("windowFn", windowFn.getClass())
+          .add(DisplayData.item("windowFn", windowFn.getClass()))
           .include(windowFn)
-          .addIfNotNull("allowedLateness", allowedLateness);
+          .addIfNotNull(DisplayData.item("allowedLateness", allowedLateness));
 
       if (trigger != null && !(trigger instanceof DefaultTrigger)) {
-        builder.add("trigger", trigger.toString());
+        builder.add(DisplayData.item("trigger", trigger.toString()));
       }
 
       if (mode != null) {
-        builder.add("accumulationMode", mode.toString());
+        builder.add(DisplayData.item("accumulationMode", mode.toString()));
       }
 
       if (closingBehavior != null) {
-        builder.add("closingBehavior", closingBehavior.toString());
+        builder.add(DisplayData.item("closingBehavior", closingBehavior.toString()));
       }
 
       if (outputTimeFn != null) {
-        builder.add("outputTimeFn", outputTimeFn.getClass());
+        builder.add(DisplayData.item("outputTimeFn", outputTimeFn.getClass()));
       }
     }