Author: etnu
Date: Wed Aug 27 16:06:19 2008
New Revision: 689653

URL: http://svn.apache.org/viewvc?rev=689653&view=rev
Log:
Added new Preloader interface. The new rendering pipeline will use this for all 
preloading rather than the ad-hoc preloading currently being done in 
GadgetServer.

This is a part of SHINDIG-523.

The preloader is not currently used by anything other than tests. This is 
because properly using it is going to require other changes first.


Added:
    
incubator/shindig/trunk/java/common/src/main/java/org/apache/shindig/common/testing/TestExecutorService.java
    
incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/Preload.java
    
incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/Preloader.java
    
incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/PreloaderService.java
    
incubator/shindig/trunk/java/gadgets/src/test/java/org/apache/shindig/gadgets/PreloaderServiceTest.java
Modified:
    
incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/GadgetServer.java
    
incubator/shindig/trunk/java/gadgets/src/test/java/org/apache/shindig/gadgets/BasicGadgetSpecFactoryTest.java
    
incubator/shindig/trunk/java/gadgets/src/test/java/org/apache/shindig/gadgets/GadgetTestFixture.java

Added: 
incubator/shindig/trunk/java/common/src/main/java/org/apache/shindig/common/testing/TestExecutorService.java
URL: 
http://svn.apache.org/viewvc/incubator/shindig/trunk/java/common/src/main/java/org/apache/shindig/common/testing/TestExecutorService.java?rev=689653&view=auto
==============================================================================
--- 
incubator/shindig/trunk/java/common/src/main/java/org/apache/shindig/common/testing/TestExecutorService.java
 (added)
+++ 
incubator/shindig/trunk/java/common/src/main/java/org/apache/shindig/common/testing/TestExecutorService.java
 Wed Aug 27 16:06:19 2008
@@ -0,0 +1,55 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations under the License.
+ */
+package org.apache.shindig.common.testing;
+
+import java.util.Collections;
+import java.util.List;
+import java.util.concurrent.AbstractExecutorService;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * ExecutorService used for testing. Executes all tasks immediately.
+ */
+public class TestExecutorService extends AbstractExecutorService {
+    private boolean shutdown;
+
+    public void execute(Runnable command) {
+      command.run();
+    }
+
+    public boolean isTerminated() {
+      return shutdown;
+    }
+
+    public boolean isShutdown() {
+      return shutdown;
+    }
+
+    public boolean awaitTermination(long timeout, TimeUnit unit) {
+      return true;
+    }
+
+    public void shutdown() {
+      shutdown = true;
+    }
+
+    public List<Runnable> shutdownNow() {
+      shutdown();
+      return Collections.emptyList();
+    }
+}
\ No newline at end of file

Modified: 
incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/GadgetServer.java
URL: 
http://svn.apache.org/viewvc/incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/GadgetServer.java?rev=689653&r1=689652&r2=689653&view=diff
==============================================================================
--- 
incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/GadgetServer.java
 (original)
+++ 
incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/GadgetServer.java
 Wed Aug 27 16:06:19 2008
@@ -165,46 +165,46 @@
     }
     return libraries;
   }
-}
 
-/**
- * Provides a task for preloading data into the gadget content
- * TODO: Remove when new preloading is committed.
- */
-class PreloadTask implements Callable<HttpResponse> {
-  private final Preload preload;
-  private final ContentFetcherFactory preloadFetcherFactory;
-  private final GadgetContext context;
+  /**
+   * Provides a task for preloading data into the gadget content
+   * TODO: Remove when new preloading is committed.
+   */
+  private static class PreloadTask implements Callable<HttpResponse> {
+    private final Preload preload;
+    private final ContentFetcherFactory preloadFetcherFactory;
+    private final GadgetContext context;
 
-  public HttpResponse call() {
-    try {
-      HttpRequest request = new HttpRequest(Uri.fromJavaUri(preload.getHref()))
-          .setSignOwner(preload.isSignOwner())
-          .setSignViewer(preload.isSignViewer())
-          .setContainer(context.getContainer())
-          .setSecurityToken(context.getToken())
-          .setGadget(Uri.fromJavaUri(context.getUrl()));
-      switch (preload.getAuth()) {
-        case NONE:
-          return preloadFetcherFactory.get().fetch(request);
-        case SIGNED:
-          return preloadFetcherFactory.getSigningFetcher(context.getToken())
-              .fetch(request);
-        case OAUTH:
-          return preloadFetcherFactory.getOAuthFetcher(context.getToken(),
-              new OAuthArguments(preload)).fetch(request);
-        default:
-          return HttpResponse.error();
+    public HttpResponse call() {
+      try {
+        HttpRequest request = new 
HttpRequest(Uri.fromJavaUri(preload.getHref()))
+            .setSignOwner(preload.isSignOwner())
+            .setSignViewer(preload.isSignViewer())
+            .setContainer(context.getContainer())
+            .setSecurityToken(context.getToken())
+            .setGadget(Uri.fromJavaUri(context.getUrl()));
+        switch (preload.getAuth()) {
+          case NONE:
+            return preloadFetcherFactory.get().fetch(request);
+          case SIGNED:
+            return preloadFetcherFactory.getSigningFetcher(context.getToken())
+                .fetch(request);
+          case OAUTH:
+            return preloadFetcherFactory.getOAuthFetcher(context.getToken(),
+                new OAuthArguments(preload)).fetch(request);
+          default:
+            return HttpResponse.error();
+        }
+      } catch (GadgetException e) {
+        return HttpResponse.error();
       }
-    } catch (GadgetException e) {
-      return HttpResponse.error();
     }
-  }
 
-  public PreloadTask(GadgetContext context, Preload preload,
-      ContentFetcherFactory preloadFetcherFactory) {
-    this.preload = preload;
-    this.preloadFetcherFactory = preloadFetcherFactory;
-    this.context = context;
+    public PreloadTask(GadgetContext context, Preload preload,
+        ContentFetcherFactory preloadFetcherFactory) {
+      this.preload = preload;
+      this.preloadFetcherFactory = preloadFetcherFactory;
+      this.context = context;
+    }
   }
-}
\ No newline at end of file
+}

Added: 
incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/Preload.java
URL: 
http://svn.apache.org/viewvc/incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/Preload.java?rev=689653&view=auto
==============================================================================
--- 
incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/Preload.java
 (added)
+++ 
incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/Preload.java
 Wed Aug 27 16:06:19 2008
@@ -0,0 +1,31 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations under the License.
+ */
+package org.apache.shindig.gadgets;
+
+/**
+ * Contains preloaded data and methods for manipulating it.
+ */
+public interface Preload {
+
+  /**
+   * Serialize the preloaded data into json.
+   *
+   * @return A JSON object suitable for passing to 
org.json.JSONObject.put(String, Object).
+   */
+  Object toJson();
+}

Added: 
incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/Preloader.java
URL: 
http://svn.apache.org/viewvc/incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/Preloader.java?rev=689653&view=auto
==============================================================================
--- 
incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/Preloader.java
 (added)
+++ 
incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/Preloader.java
 Wed Aug 27 16:06:19 2008
@@ -0,0 +1,36 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations under the License.
+ */
+package org.apache.shindig.gadgets;
+
+import java.util.Map;
+import java.util.concurrent.Callable;
+
+/**
+ * Performs an individual preloading operation.
+ */
+public interface Preloader {
+  /**
+   * Create new preload tasks for the provided gadget.
+   *
+   * @param gadget The gadget that the operations will be performed for.
+   * @return Preloading tasks that will be executed in parallel with other 
preloading tasks by
+   * [EMAIL PROTECTED] PreloaderService#preload(Gadget)}. Callables will be 
converted to Futures for lazy
+   * evaluation.
+   */
+  Map<String, Callable<Preload>> createPreloadTasks(Gadget gadget);
+}

Added: 
incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/PreloaderService.java
URL: 
http://svn.apache.org/viewvc/incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/PreloaderService.java?rev=689653&view=auto
==============================================================================
--- 
incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/PreloaderService.java
 (added)
+++ 
incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/PreloaderService.java
 Wed Aug 27 16:06:19 2008
@@ -0,0 +1,62 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations under the License.
+ */
+package org.apache.shindig.gadgets;
+
+import com.google.common.collect.Maps;
+import com.google.inject.Inject;
+
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.Callable;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Future;
+
+/**
+ * Handles preloading operations, such as HTTP fetches, social data retrieval, 
or anything else that
+ * would benefit from preloading on the server instead of incurring a network 
request for users.
+ *
+ * Preloads will be fetched concurrently using the injected ExecutorService, 
and they can be read
+ * lazily using the returned map of futures.
+ */
+public class PreloaderService {
+  private final ExecutorService executor;
+  private final List<? extends Preloader> preloaders;
+
+  @Inject
+  public PreloaderService(ExecutorService executor, List<? extends Preloader> 
preloaders) {
+    this.executor = executor;
+    this.preloaders = preloaders;
+  }
+
+  /**
+   * Begin all preload operations.
+   *
+   * @param gadget The gadget to perform preloading for.
+   * @return A map of all preloaded data. Callers can retrieve preloads by 
unique key.
+   */
+  public Map<String, Future<Preload>> preload(Gadget gadget) {
+    Map<String, Future<Preload>> preloads = Maps.newHashMap();
+    for (Preloader preloader : preloaders) {
+      Map<String, Callable<Preload>> tasks = 
preloader.createPreloadTasks(gadget);
+      for (Map.Entry<String, Callable<Preload>> entry : tasks.entrySet()) {
+        preloads.put(entry.getKey(), executor.submit(entry.getValue()));
+      }
+    }
+    return preloads;
+  }
+}

Modified: 
incubator/shindig/trunk/java/gadgets/src/test/java/org/apache/shindig/gadgets/BasicGadgetSpecFactoryTest.java
URL: 
http://svn.apache.org/viewvc/incubator/shindig/trunk/java/gadgets/src/test/java/org/apache/shindig/gadgets/BasicGadgetSpecFactoryTest.java?rev=689653&r1=689652&r2=689653&view=diff
==============================================================================
--- 
incubator/shindig/trunk/java/gadgets/src/test/java/org/apache/shindig/gadgets/BasicGadgetSpecFactoryTest.java
 (original)
+++ 
incubator/shindig/trunk/java/gadgets/src/test/java/org/apache/shindig/gadgets/BasicGadgetSpecFactoryTest.java
 Wed Aug 27 16:06:19 2008
@@ -21,6 +21,7 @@
 import org.apache.shindig.common.cache.CacheProvider;
 import org.apache.shindig.common.cache.DefaultCacheProvider;
 import org.apache.shindig.common.uri.Uri;
+import org.apache.shindig.common.testing.TestExecutorService;
 import org.apache.shindig.gadgets.http.HttpFetcher;
 import org.apache.shindig.gadgets.http.HttpRequest;
 import org.apache.shindig.gadgets.http.HttpResponse;
@@ -39,11 +40,7 @@
 import org.junit.Test;
 
 import java.net.URI;
-import java.util.Collections;
-import java.util.List;
-import java.util.concurrent.AbstractExecutorService;
 import java.util.concurrent.ExecutorService;
-import java.util.concurrent.TimeUnit;
 
 /**
  * Tests for BasicGadgetSpecFactory
@@ -85,34 +82,7 @@
       return SPEC_URL.toJavaUri();
     }
   };
-  private final static ExecutorService FAKE_EXECUTOR = new 
AbstractExecutorService() {
-    private boolean shutdown;
-
-    public void execute(Runnable command) {
-      command.run();
-    }
-
-    public boolean isTerminated() {
-      return shutdown;
-    }
-
-    public boolean isShutdown() {
-      return shutdown;
-    }
-
-    public boolean awaitTermination(long timeout, TimeUnit unit) {
-      return true;
-    }
-
-    public void shutdown() {
-      shutdown = true;
-    }
-
-    public List<Runnable> shutdownNow() {
-      shutdown();
-      return Collections.emptyList();
-    }
-  };
+  private final static ExecutorService FAKE_EXECUTOR = new 
TestExecutorService();
 
   private final HttpFetcher fetcher = 
EasyMock.createNiceMock(HttpFetcher.class);
   private final CaptureRewriter rewriter = new CaptureRewriter();

Modified: 
incubator/shindig/trunk/java/gadgets/src/test/java/org/apache/shindig/gadgets/GadgetTestFixture.java
URL: 
http://svn.apache.org/viewvc/incubator/shindig/trunk/java/gadgets/src/test/java/org/apache/shindig/gadgets/GadgetTestFixture.java?rev=689653&r1=689652&r2=689653&view=diff
==============================================================================
--- 
incubator/shindig/trunk/java/gadgets/src/test/java/org/apache/shindig/gadgets/GadgetTestFixture.java
 (original)
+++ 
incubator/shindig/trunk/java/gadgets/src/test/java/org/apache/shindig/gadgets/GadgetTestFixture.java
 Wed Aug 27 16:06:19 2008
@@ -21,6 +21,7 @@
 
 import org.apache.shindig.common.ContainerConfig;
 import org.apache.shindig.common.SecurityTokenDecoder;
+import org.apache.shindig.common.testing.TestExecutorService;
 import org.apache.shindig.common.cache.CacheProvider;
 import org.apache.shindig.common.cache.DefaultCacheProvider;
 import org.apache.shindig.common.util.FakeTimeSource;
@@ -36,11 +37,7 @@
 import org.apache.shindig.gadgets.servlet.JsonRpcHandler;
 import org.apache.shindig.gadgets.servlet.UrlGenerator;
 
-import java.util.List;
-import java.util.Collections;
-import java.util.concurrent.AbstractExecutorService;
 import java.util.concurrent.ExecutorService;
-import java.util.concurrent.TimeUnit;
 
 import javax.servlet.http.HttpServletRequest;
 import javax.servlet.http.HttpServletResponse;
@@ -71,34 +68,7 @@
   public final LockedDomainService lockedDomainService = 
mock(LockedDomainService.class);
   public final ContentRewriter rewriter = new NoOpContentRewriter();
   public final FakeTimeSource timeSource = new FakeTimeSource();
-  public final ExecutorService executor = new AbstractExecutorService() {
-    private boolean shutdown;
-
-    public void execute(Runnable command) {
-      command.run();
-    }
-
-    public boolean isTerminated() {
-      return shutdown;
-    }
-
-    public boolean isShutdown() {
-      return shutdown;
-    }
-
-    public boolean awaitTermination(long timeout, TimeUnit unit) {
-      return true;
-    }
-
-    public void shutdown() {
-      shutdown = true;
-    }
-
-    public List<Runnable> shutdownNow() {
-      shutdown();
-      return Collections.emptyList();
-    }
-  };
+  public final ExecutorService executor = new TestExecutorService();
   public final GadgetSpecFactory specFactory = new BasicGadgetSpecFactory(
       fetcher, cacheProvider, new BasicContentRewriterRegistry(null), 
executor, 0, 0L, 0L);
 

Added: 
incubator/shindig/trunk/java/gadgets/src/test/java/org/apache/shindig/gadgets/PreloaderServiceTest.java
URL: 
http://svn.apache.org/viewvc/incubator/shindig/trunk/java/gadgets/src/test/java/org/apache/shindig/gadgets/PreloaderServiceTest.java?rev=689653&view=auto
==============================================================================
--- 
incubator/shindig/trunk/java/gadgets/src/test/java/org/apache/shindig/gadgets/PreloaderServiceTest.java
 (added)
+++ 
incubator/shindig/trunk/java/gadgets/src/test/java/org/apache/shindig/gadgets/PreloaderServiceTest.java
 Wed Aug 27 16:06:19 2008
@@ -0,0 +1,127 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations under the License.
+ */
+package org.apache.shindig.gadgets;
+
+import org.apache.shindig.common.testing.TestExecutorService;
+
+import com.google.common.collect.Maps;
+import static org.junit.Assert.assertEquals;
+import org.junit.Test;
+
+import java.util.Arrays;
+import java.util.Map;
+import java.util.concurrent.Callable;
+import java.util.concurrent.Future;
+
+/**
+ * Tests for PreloaderService.
+ */
+public class PreloaderServiceTest {
+  private static final String PRELOAD_STRING_KEY = "key a";
+  private static final String PRELOAD_NUMERIC_KEY = "key b";
+  private static final String PRELOAD_MAP_KEY = "key c";
+  private static final String PRELOAD_BEAN_KEY = "key d";
+  private static final String PRELOAD_STRING_VALUE = "Some random string";
+  private static final Integer PRELOAD_NUMERIC_VALUE = 5;
+  private static final Map<String, String> PRELOAD_MAP_VALUE
+      = Maps.immutableMap("foo", "bar", "baz", "blah");
+  private static final Object PRELOAD_BEAN_VALUE = new Object() {
+    public String getFoo() {
+      return "foo";
+    }
+
+    public String getBar() {
+      return "bar";
+    }
+  };
+
+  private final TestPreloader preloader = new TestPreloader();
+  private final TestPreloader preloader2 = new TestPreloader();
+
+  @Test
+  public void preloadSingleService() throws Exception {
+    preloader.tasks.put(PRELOAD_STRING_KEY,
+        new TestPreloadCallable(new DataPreload(PRELOAD_STRING_VALUE)));
+
+    PreloaderService service
+        = new PreloaderService(new TestExecutorService(), 
Arrays.asList(preloader));
+
+    assertEquals(PRELOAD_STRING_VALUE,
+                
(String)service.preload(null).get(PRELOAD_STRING_KEY).get().toJson());
+  }
+
+  @Test
+  public void preloadMultipleServices() throws Exception {
+    preloader.tasks.put(PRELOAD_STRING_KEY,
+        new TestPreloadCallable(new DataPreload(PRELOAD_STRING_VALUE)));
+
+    preloader.tasks.put(PRELOAD_NUMERIC_KEY,
+        new TestPreloadCallable(new DataPreload(PRELOAD_NUMERIC_VALUE)));
+
+    preloader2.tasks.put(PRELOAD_MAP_KEY,
+        new TestPreloadCallable(new DataPreload(PRELOAD_MAP_VALUE)));
+
+    preloader2.tasks.put(PRELOAD_BEAN_KEY,
+        new TestPreloadCallable(new DataPreload(PRELOAD_BEAN_VALUE)));
+
+    PreloaderService service
+        = new PreloaderService(new TestExecutorService(), 
Arrays.asList(preloader, preloader2));
+
+    Map<String, Future<Preload>> preloads = service.preload(null);
+
+    assertEquals(PRELOAD_STRING_VALUE,
+                 (String) preloads.get(PRELOAD_STRING_KEY).get().toJson());
+    assertEquals(PRELOAD_NUMERIC_VALUE,
+                 (Integer) preloads.get(PRELOAD_NUMERIC_KEY).get().toJson());
+    assertEquals(PRELOAD_MAP_VALUE,
+                 (Map) preloads.get(PRELOAD_MAP_KEY).get().toJson());
+    assertEquals(PRELOAD_BEAN_VALUE, 
preloads.get(PRELOAD_BEAN_KEY).get().toJson());
+  }
+
+  private static class TestPreloader implements Preloader {
+    private final Map<String, Callable<Preload>> tasks = Maps.newHashMap();
+
+    public Map<String, Callable<Preload>> createPreloadTasks(Gadget gadget) {
+      return tasks;
+    }
+  }
+
+  private static class TestPreloadCallable implements Callable<Preload> {
+    private final Preload preload;
+
+    public TestPreloadCallable(Preload preload) {
+      this.preload = preload;
+    }
+
+    public Preload call() {
+      return preload;
+    }
+  }
+
+  private static class DataPreload implements Preload {
+    private final Object data;
+
+    public DataPreload(Object data) {
+      this.data = data;
+    }
+
+    public Object toJson() {
+      return data;
+    }
+  }
+}


Reply via email to