Author: yurize
Date: Sat Nov 26 19:09:44 2011
New Revision: 1206546

URL: http://svn.apache.org/viewvc?rev=1206546&view=rev
Log:
Refactors the SearchService related classes to allow easier integration of 
alternative search provider https://reviews.apache.org/r/2882/

Modified:
    incubator/wave/trunk/src/com/google/wave/api/SearchResult.java
    incubator/wave/trunk/src/com/google/wave/api/impl/GsonFactory.java
    
incubator/wave/trunk/src/org/waveprotocol/box/server/robots/operations/SearchService.java
    
incubator/wave/trunk/src/org/waveprotocol/box/server/waveserver/SearchProvider.java
    incubator/wave/trunk/src/org/waveprotocol/box/server/waveserver/WaveMap.java
    
incubator/wave/trunk/test/org/waveprotocol/box/server/robots/operations/SearchServiceTest.java
    
incubator/wave/trunk/test/org/waveprotocol/box/server/waveserver/WaveMapTest.java
    
incubator/wave/trunk/test/org/waveprotocol/box/server/waveserver/WaveServerTest.java

Modified: incubator/wave/trunk/src/com/google/wave/api/SearchResult.java
URL: 
http://svn.apache.org/viewvc/incubator/wave/trunk/src/com/google/wave/api/SearchResult.java?rev=1206546&r1=1206545&r2=1206546&view=diff
==============================================================================
--- incubator/wave/trunk/src/com/google/wave/api/SearchResult.java (original)
+++ incubator/wave/trunk/src/com/google/wave/api/SearchResult.java Sat Nov 26 
19:09:44 2011
@@ -32,17 +32,19 @@ public class SearchResult {
     private final String snippet;
     private final String waveId;
     private final long lastModified;
+    private final long created;
     private final int unreadCount;
     private final int blipCount;
     private final List<String> participants;
 
     public Digest(String title, String snippet, String waveId, List<String> 
participants,
-                  long lastModified, int unreadCount, int blipCount) {
+                  long lastModified, long created, int unreadCount, int 
blipCount) {
       this.title = title;
       this.snippet = snippet;
       this.waveId = waveId;
       this.participants = new ArrayList<String>(participants);
       this.lastModified = lastModified;
+      this.created = created;
       this.unreadCount = unreadCount;
       this.blipCount = blipCount;
     }
@@ -66,6 +68,10 @@ public class SearchResult {
     public long getLastModified() {
       return lastModified;
     }
+    
+    public long getCreated() {
+      return created;
+    }
 
     public int getUnreadCount() {
       return unreadCount;

Modified: incubator/wave/trunk/src/com/google/wave/api/impl/GsonFactory.java
URL: 
http://svn.apache.org/viewvc/incubator/wave/trunk/src/com/google/wave/api/impl/GsonFactory.java?rev=1206546&r1=1206545&r2=1206546&view=diff
==============================================================================
--- incubator/wave/trunk/src/com/google/wave/api/impl/GsonFactory.java 
(original)
+++ incubator/wave/trunk/src/com/google/wave/api/impl/GsonFactory.java Sat Nov 
26 19:09:44 2011
@@ -181,11 +181,12 @@ public class GsonFactory {
   /**
    * An instance creator that creates an empty {@link SearchResult.Digest}.
    */
-  private static class SearchResultDigestInstanceCreator implements 
InstanceCreator<SearchResult.Digest> {
+  private static class SearchResultDigestInstanceCreator implements
+      InstanceCreator<SearchResult.Digest> {
     @Override
     public SearchResult.Digest createInstance(Type type) {
       List<String> participants = Lists.newLinkedList();
-      return new SearchResult.Digest("", "", "", participants, -1, -1, -1);
+      return new SearchResult.Digest("", "", "", participants, -1, -1, -1, -1);
     }
   }
 }

Modified: 
incubator/wave/trunk/src/org/waveprotocol/box/server/robots/operations/SearchService.java
URL: 
http://svn.apache.org/viewvc/incubator/wave/trunk/src/org/waveprotocol/box/server/robots/operations/SearchService.java?rev=1206546&r1=1206545&r2=1206546&view=diff
==============================================================================
--- 
incubator/wave/trunk/src/org/waveprotocol/box/server/robots/operations/SearchService.java
 (original)
+++ 
incubator/wave/trunk/src/org/waveprotocol/box/server/robots/operations/SearchService.java
 Sat Nov 26 19:09:44 2011
@@ -17,49 +17,16 @@
 
 package org.waveprotocol.box.server.robots.operations;
 
-import com.google.common.annotations.VisibleForTesting;
 import com.google.common.collect.ImmutableMap;
 import com.google.inject.Inject;
-import com.google.wave.api.ApiIdSerializer;
 import com.google.wave.api.InvalidRequestException;
 import com.google.wave.api.JsonRpcConstant.ParamsProperty;
 import com.google.wave.api.OperationRequest;
 import com.google.wave.api.SearchResult;
-import com.google.wave.api.SearchResult.Digest;
-
-import org.waveprotocol.box.common.Snippets;
 import org.waveprotocol.box.server.robots.OperationContext;
-import org.waveprotocol.box.server.robots.util.ConversationUtil;
 import org.waveprotocol.box.server.robots.util.OperationUtil;
 import org.waveprotocol.box.server.waveserver.SearchProvider;
-import org.waveprotocol.wave.model.conversation.BlipIterators;
-import org.waveprotocol.wave.model.conversation.ConversationBlip;
-import org.waveprotocol.wave.model.conversation.ObservableConversation;
-import org.waveprotocol.wave.model.conversation.ObservableConversationBlip;
-import org.waveprotocol.wave.model.conversation.ObservableConversationView;
-import org.waveprotocol.wave.model.conversation.TitleHelper;
-import org.waveprotocol.wave.model.conversation.WaveletBasedConversation;
-import org.waveprotocol.wave.model.document.Document;
-import org.waveprotocol.wave.model.id.IdUtil;
-import org.waveprotocol.wave.model.id.ModernIdSerialiser;
-import org.waveprotocol.wave.model.id.WaveletId;
-import org.waveprotocol.wave.model.supplement.PrimitiveSupplement;
-import org.waveprotocol.wave.model.supplement.PrimitiveSupplementImpl;
-import org.waveprotocol.wave.model.supplement.SupplementedWave;
-import org.waveprotocol.wave.model.supplement.SupplementedWaveImpl;
-import 
org.waveprotocol.wave.model.supplement.SupplementedWaveImpl.DefaultFollow;
-import org.waveprotocol.wave.model.supplement.WaveletBasedSupplement;
-import org.waveprotocol.wave.model.util.CollectionUtils;
 import org.waveprotocol.wave.model.wave.ParticipantId;
-import org.waveprotocol.wave.model.wave.data.ObservableWaveletData;
-import org.waveprotocol.wave.model.wave.data.WaveViewData;
-import org.waveprotocol.wave.model.wave.data.WaveletData;
-import org.waveprotocol.wave.model.wave.opbased.OpBasedWavelet;
-
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.List;
 import java.util.Map;
 
 /**
@@ -75,17 +42,12 @@ public class SearchService implements Op
    * Defined in the spec.
    */
   private static final int DEFAULT_NUMBER_SEARCH_RESULTS = 10;
-  private static final int DIGEST_SNIPPET_LENGTH = 140;
-  private static final int PARTICIPANTS_SNIPPET_LENGTH = 5;
-  private static final String EMPTY_WAVELET_TITLE = "";
 
   private final SearchProvider searchProvider;
-  private final ConversationUtil conversationUtil;
 
   @Inject
-  public SearchService(SearchProvider searchProvider, ConversationUtil 
conversationUtil) {
+  public SearchService(SearchProvider searchProvider) {
     this.searchProvider = searchProvider;
-    this.conversationUtil = conversationUtil;
   }
 
   @Override
@@ -104,169 +66,9 @@ public class SearchService implements Op
     context.constructResponse(operation, data);
   }
 
-  /**
-   * Produces a digest for a set of conversations. Never returns null.
-   *
-   * @param conversations the conversation.
-   * @param supplement the supplement that allows to easily perform various
-   *        queries on user related state of the wavelet.
-   * @param rawWaveletData the waveletData from which the digest is generated.
-   *        This wavelet is a copy.
-   * @return the server representation of the digest for the query.
-   */
-  @VisibleForTesting
-  Digest generateDigest(ObservableConversationView conversations, 
SupplementedWave supplement,
-      WaveletData rawWaveletData) {
-    ObservableConversation rootConversation = conversations.getRoot();
-    ObservableConversationBlip firstBlip = null;
-    if (rootConversation != null && rootConversation.getRootThread() != null
-        && rootConversation.getRootThread().getFirstBlip() != null) {
-      firstBlip = rootConversation.getRootThread().getFirstBlip();
-    }
-    String title;
-    if (firstBlip != null) {
-      Document firstBlipContents = firstBlip.getContent();
-      title = TitleHelper.extractTitle(firstBlipContents).trim();
-    } else {
-      title = EMPTY_WAVELET_TITLE;
-    }
-
-    String snippet = Snippets.renderSnippet(rawWaveletData, 
DIGEST_SNIPPET_LENGTH).trim();
-    if (snippet.startsWith(title) && !title.isEmpty()) {
-      // Strip the title from the snippet if the snippet starts with the title.
-      snippet = snippet.substring(title.length());
-    }
-    String waveId = 
ApiIdSerializer.instance().serialiseWaveId(rawWaveletData.getWaveId());
-    List<String> participants = CollectionUtils.newArrayList();
-    for (ParticipantId p : rawWaveletData.getParticipants()) {
-      if (participants.size() < PARTICIPANTS_SNIPPET_LENGTH) {
-        participants.add(p.getAddress());
-      } else {
-        break;
-      }
-    }
-    int unreadCount = 0;
-    int blipCount = 0;
-    for (ConversationBlip blip : BlipIterators.breadthFirst(rootConversation)) 
{
-      if (supplement.isUnread(blip)) {
-        unreadCount++;
-      }
-      blipCount++;
-    }
-    return new Digest(title, snippet, waveId, participants, 
rawWaveletData.getLastModifiedTime(),
-        unreadCount, blipCount);
-  }
-
-  /** @return a digest for an empty wave. */
-  private Digest emptyDigest(WaveViewData wave) {
-    String title = 
ModernIdSerialiser.INSTANCE.serialiseWaveId(wave.getWaveId());
-    String id = ApiIdSerializer.instance().serialiseWaveId(wave.getWaveId());
-    return new Digest(title, "(empty)", id, Collections.<String> emptyList(), 
-1L, 0, 0);
-  }
-
-  /** @return a digest for an unrecognised type of wave. */
-  private Digest unknownDigest(WaveViewData wave) {
-    String title = 
ModernIdSerialiser.INSTANCE.serialiseWaveId(wave.getWaveId());
-    String id = ApiIdSerializer.instance().serialiseWaveId(wave.getWaveId());
-    long lmt = -1L;
-    int docs = 0;
-    List<String> participants = new ArrayList<String>();
-    for (WaveletData data : wave.getWavelets()) {
-      lmt = Math.max(lmt, data.getLastModifiedTime());
-      docs += data.getDocumentIds().size();
-
-      for (ParticipantId p : data.getParticipants()) {
-        if (participants.size() < PARTICIPANTS_SNIPPET_LENGTH) {
-          participants.add(p.getAddress());
-        } else {
-          break;
-        }
-      }
-    }
-    return new Digest(title, "(unknown)", id, participants, lmt, 0, docs);
-  }
-
   // Note that this search implementation is only of prototype quality.
   private SearchResult search(
       ParticipantId participant, String query, int startAt, int numResults) {
-    Collection<WaveViewData> results =
-        searchProvider.search(participant, query, startAt, numResults);
-
-    // Generate exactly one digest per wave. This includes conversational and
-    // non-conversational waves. The position-based API for search prevents the
-    // luxury of extra filtering here. Filtering can only be done in the
-    // searchProvider. All waves returned by the search provider must be
-    // included in the search result.
-    SearchResult result = new SearchResult(query);
-    for (WaveViewData wave : results) {
-      // Note: the indexing infrastructure only supports single-conversation
-      // waves, and requires raw wavelet access for snippeting.
-      ObservableWaveletData root = null;
-      ObservableWaveletData other = null;
-      ObservableWaveletData udw = null;
-      for (ObservableWaveletData waveletData : wave.getWavelets()) {
-        WaveletId waveletId = waveletData.getWaveletId();
-        if (IdUtil.isConversationRootWaveletId(waveletId)) {
-          root = waveletData;
-        } else if (IdUtil.isConversationalId(waveletId)) {
-          other = waveletData;
-        } else if (IdUtil.isUserDataWavelet(waveletId)) {
-          // assume this is the user data wavelet for the right user.
-          udw = waveletData;
-        }
-      }
-
-      ObservableWaveletData convWavelet = root != null ? root : other;
-      SupplementedWave supplement = null;
-      ObservableConversationView conversations = null;
-      if (convWavelet != null) {
-        OpBasedWavelet wavelet = OpBasedWavelet.createReadOnly(convWavelet);
-        if (WaveletBasedConversation.waveletHasConversation(wavelet)) {
-          conversations = conversationUtil.buildConversation(wavelet);
-          supplement = buildSupplement(participant, conversations, udw);
-        }
-      }
-      if (conversations != null) {
-        // This is a conversational wave. Produce a conversational digest.
-        result.addDigest(generateDigest(conversations, supplement, 
convWavelet));
-      } else {
-        // It is unknown how to present this wave.
-        result.addDigest(generateEmptyorUnknownDigest(wave));
-      }
-    }
-
-    assert result.getDigests().size() == results.size();
-    return result;
-  }
-
-  /**
-   * Generates an empty digest in case the wave is empty, or an unknown digest
-   * otherwise.
-   *
-   * @param wave the wave.
-   * @return the generated digest.
-   */
-  Digest generateEmptyorUnknownDigest(WaveViewData wave) {
-    boolean empty = !wave.getWavelets().iterator().hasNext();
-    Digest digest = empty ? emptyDigest(wave) : unknownDigest(wave);
-    return digest;
-  }
-
-  /**
-   * Builds the supplement model from a wave. Never returns null.
-   *
-   * @param viewer the participant for which the supplement is constructed.
-   * @param conversations conversations in the wave
-   * @param udw the user data wavelet for the logged user.
-   * @return the wave supplement.
-   */
-  @VisibleForTesting
-  SupplementedWave buildSupplement(
-      ParticipantId viewer, ObservableConversationView conversations, 
ObservableWaveletData udw) {
-    // Use mock state if there is no UDW.
-    PrimitiveSupplement udwState =
-        udw != null ? 
WaveletBasedSupplement.create(OpBasedWavelet.createReadOnly(udw))
-            : new PrimitiveSupplementImpl();
-    return SupplementedWaveImpl.create(udwState, conversations, viewer, 
DefaultFollow.ALWAYS);
+    return searchProvider.search(participant, query, startAt, numResults);
   }
 }

Modified: 
incubator/wave/trunk/src/org/waveprotocol/box/server/waveserver/SearchProvider.java
URL: 
http://svn.apache.org/viewvc/incubator/wave/trunk/src/org/waveprotocol/box/server/waveserver/SearchProvider.java?rev=1206546&r1=1206545&r2=1206546&view=diff
==============================================================================
--- 
incubator/wave/trunk/src/org/waveprotocol/box/server/waveserver/SearchProvider.java
 (original)
+++ 
incubator/wave/trunk/src/org/waveprotocol/box/server/waveserver/SearchProvider.java
 Sat Nov 26 19:09:44 2011
@@ -17,10 +17,10 @@
 
 package org.waveprotocol.box.server.waveserver;
 
+import com.google.wave.api.SearchResult;
+
 import org.waveprotocol.wave.model.wave.ParticipantId;
-import org.waveprotocol.wave.model.wave.data.WaveViewData;
 
-import java.util.Collection;
 
 /**
  * A provider of search results. SearchProviders can be queried, and reply 
with a set of
@@ -36,8 +36,8 @@ public interface SearchProvider {
    * @param query the query string
    * @param startAt The offset in the results to return
    * @param numResults The number of results from startAt to return
-   * @return the wavelets which match the specified query
+   * @return the search result with digests which match the specified query
    */
-  Collection<WaveViewData> search(
+  SearchResult search(
       ParticipantId user, String query, int startAt, int numResults);
 }

Modified: 
incubator/wave/trunk/src/org/waveprotocol/box/server/waveserver/WaveMap.java
URL: 
http://svn.apache.org/viewvc/incubator/wave/trunk/src/org/waveprotocol/box/server/waveserver/WaveMap.java?rev=1206546&r1=1206545&r2=1206546&view=diff
==============================================================================
--- 
incubator/wave/trunk/src/org/waveprotocol/box/server/waveserver/WaveMap.java 
(original)
+++ 
incubator/wave/trunk/src/org/waveprotocol/box/server/waveserver/WaveMap.java 
Sat Nov 26 19:09:44 2011
@@ -34,7 +34,7 @@ import com.google.common.util.concurrent
 import com.google.common.util.concurrent.ListenableFutureTask;
 import com.google.inject.Inject;
 import com.google.inject.name.Named;
-
+import com.google.wave.api.SearchResult;
 import org.waveprotocol.box.common.DeltaSequence;
 import org.waveprotocol.box.common.ExceptionalIterator;
 import org.waveprotocol.box.server.CoreSettings;
@@ -555,6 +555,7 @@ public class WaveMap implements SearchPr
   
   private final ConcurrentMap<WaveId, Wave> waves;
   private final WaveletStore<?> store;
+  private final WaveDigester digester;
 
   /** The computing map that holds wave viev per each online user.*/
   private final ConcurrentMap<ParticipantId, Multimap<WaveId, WaveletId>> 
explicitPerUserWaveViews;
@@ -613,11 +614,13 @@ public class WaveMap implements SearchPr
       WaveBus dispatcher,
       final LocalWaveletContainer.Factory localFactory,
       final RemoteWaveletContainer.Factory remoteFactory,
-      @Named(CoreSettings.WAVE_SERVER_DOMAIN) final String waveDomain) {
+      @Named(CoreSettings.WAVE_SERVER_DOMAIN) final String waveDomain,
+      WaveDigester digester) {
     // NOTE(anorth): DeltaAndSnapshotStore is more specific than necessary, but
     // helps Guice out.
     // TODO(soren): inject a proper executor (with a pool of configurable size)
     this.store = waveletStore;
+    this.digester = digester;
     sharedDomainParticipantId = 
ParticipantIdUtil.makeUnsafeSharedDomainParticipantId(waveDomain);
     dispatcher.subscribe(subscriber);
     final Executor lookupExecutor = Executors.newSingleThreadExecutor();
@@ -686,7 +689,7 @@ public class WaveMap implements SearchPr
   }
 
   @Override
-  public Collection<WaveViewData> search(final ParticipantId user, String 
query, int startAt,
+  public SearchResult search(final ParticipantId user, String query, int 
startAt,
       int numResults) {
     LOG.fine("Search query '" + query + "' from user: " + user + " [" + 
startAt + ", "
         + (startAt + numResults - 1) + "]");
@@ -696,7 +699,7 @@ public class WaveMap implements SearchPr
     } catch (QueryHelper.InvalidQueryException e1) {
       // Invalid query param - stop and return empty search results.
       LOG.warning("Invalid Query. " + e1.getMessage());
-      return Collections.emptyList();
+      return digester.generateSearchResult(user, query, null);
     }
     final List<ParticipantId> withParticipantIds;
     final List<ParticipantId> creatorParticipantIds;
@@ -712,7 +715,7 @@ public class WaveMap implements SearchPr
     } catch (InvalidParticipantAddress e) {
       // Invalid address - stop and return empty search results.
       LOG.warning("Invalid participantId: " + e.getAddress() + " in query: " + 
query);
-      return Collections.emptyList();
+      return digester.generateSearchResult(user, query, null);
     }
     // Maybe should be changed in case other folders in addition to 'inbox' are
     // added.
@@ -772,9 +775,6 @@ public class WaveMap implements SearchPr
       if (view != null) {
          results.put(waveId, view);
       }
-      // TODO (Yuri Z.) Investigate if it worth to keep the waves views sorted
-      // by LMT so we can stop looping after we have (startAt + numResults)
-      // results.
     }
     List<WaveViewData> searchResultslist = null;
     int searchResultSize = results.values().size();
@@ -789,11 +789,12 @@ public class WaveMap implements SearchPr
     }
     LOG.info("Search response to '" + query + "': " + searchResultslist.size() 
+ " results, user: "
         + user);
-    // Memory management wise it's dangerous to return a sublist of a much
-    // longer list, therefore, we return a 'defensive' copy.
-    return ImmutableList.copyOf(searchResultslist);
+    // Memory management wise it's dangerous to expose a sublist of a much
+    // longer list, therefore, we expose a 'defensive' copy.
+    Collection<WaveViewData> l = ImmutableList.copyOf(searchResultslist);
+    return digester.generateSearchResult(user, query, l);
   }
-
+  
   /**
    * Verifies whether the wavelet matches the filter criteria.
    * 

Modified: 
incubator/wave/trunk/test/org/waveprotocol/box/server/robots/operations/SearchServiceTest.java
URL: 
http://svn.apache.org/viewvc/incubator/wave/trunk/test/org/waveprotocol/box/server/robots/operations/SearchServiceTest.java?rev=1206546&r1=1206545&r2=1206546&view=diff
==============================================================================
--- 
incubator/wave/trunk/test/org/waveprotocol/box/server/robots/operations/SearchServiceTest.java
 (original)
+++ 
incubator/wave/trunk/test/org/waveprotocol/box/server/robots/operations/SearchServiceTest.java
 Sat Nov 26 19:09:44 2011
@@ -19,8 +19,6 @@ package org.waveprotocol.box.server.robo
 
 import static org.mockito.Matchers.argThat;
 import static org.mockito.Matchers.eq;
-import static org.mockito.Mockito.any;
-import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.when;
 import static 
org.waveprotocol.box.server.util.testing.TestingConstants.OTHER_PARTICIPANT;
@@ -45,42 +43,13 @@ import org.hamcrest.Matcher;
 import org.mockito.Mock;
 import org.mockito.MockitoAnnotations;
 import org.waveprotocol.box.server.robots.OperationContext;
-import org.waveprotocol.box.server.robots.util.ConversationUtil;
-import org.waveprotocol.box.server.util.WaveletDataUtil;
 import org.waveprotocol.box.server.waveserver.SearchProvider;
-import org.waveprotocol.wave.model.conversation.Conversation;
-import org.waveprotocol.wave.model.conversation.ConversationBlip;
-import org.waveprotocol.wave.model.conversation.ConversationView;
-import org.waveprotocol.wave.model.conversation.ObservableConversationView;
-import org.waveprotocol.wave.model.conversation.TitleHelper;
-import org.waveprotocol.wave.model.conversation.WaveBasedConversationView;
-import org.waveprotocol.wave.model.conversation.WaveletBasedConversation;
-import org.waveprotocol.wave.model.document.util.LineContainers;
-import org.waveprotocol.wave.model.document.util.XmlStringBuilder;
-import org.waveprotocol.wave.model.id.IdGenerator;
 import org.waveprotocol.wave.model.id.WaveId;
 import org.waveprotocol.wave.model.id.WaveletId;
-import org.waveprotocol.wave.model.operation.SilentOperationSink;
-import 
org.waveprotocol.wave.model.operation.wave.BasicWaveletOperationContextFactory;
-import org.waveprotocol.wave.model.operation.wave.WaveletOperation;
-import org.waveprotocol.wave.model.supplement.SupplementedWave;
-import org.waveprotocol.wave.model.testing.BasicFactories;
-import org.waveprotocol.wave.model.testing.FakeIdGenerator;
-import org.waveprotocol.wave.model.version.HashedVersion;
-import org.waveprotocol.wave.model.wave.ObservableWavelet;
 import org.waveprotocol.wave.model.wave.ParticipantId;
-import org.waveprotocol.wave.model.wave.ParticipationHelper;
-import org.waveprotocol.wave.model.wave.ReadOnlyWaveView;
-import org.waveprotocol.wave.model.wave.data.ObservableWaveletData;
 import org.waveprotocol.wave.model.wave.data.WaveViewData;
-import org.waveprotocol.wave.model.wave.data.WaveletData;
-import org.waveprotocol.wave.model.wave.data.impl.WaveViewDataImpl;
-import org.waveprotocol.wave.model.wave.data.impl.WaveletDataImpl;
-import org.waveprotocol.wave.model.wave.opbased.OpBasedWavelet;
-
 import java.util.Arrays;
 import java.util.Collection;
-import java.util.List;
 import java.util.Map;
 import java.util.Set;
 
@@ -99,87 +68,25 @@ public class SearchServiceTest extends T
   @Mock private SearchProvider searchProvider;
   @Mock private OperationRequest operation;
   @Mock private OperationContext context;
-  @Mock private IdGenerator idGenerator;
   
-  private ConversationUtil conversationUtil;
-
-  /**
-   * Builds a wavelet and provides direct access to the various layers of
-   * abstraction.
-   */
-  private static class TestingWaveletData {
-    private final ObservableWaveletData waveletData;
-    private final ObservableWaveletData userWaveletData;
-    private final Conversation conversation;
-    private final WaveViewData waveViewData;
-
-    public TestingWaveletData(
-        WaveId waveId, WaveletId waveletId, ParticipantId author, boolean 
isConversational) {
-      waveletData =
-          new WaveletDataImpl(waveletId, author, 1234567890, 0, 
HashedVersion.unsigned(0), 0,
-              waveId, 
BasicFactories.observablePluggableMutableDocumentFactory());
-      userWaveletData =
-          new WaveletDataImpl(WaveletId.of("example.com", 
"[email protected]"), author,
-              1234567890, 0, HashedVersion.unsigned(0), 0,
-            waveId, 
BasicFactories.observablePluggableMutableDocumentFactory());
-      
-      OpBasedWavelet wavelet =
-        new OpBasedWavelet(waveId, waveletData, new 
BasicWaveletOperationContextFactory(author),
-            ParticipationHelper.DEFAULT,
-            SilentOperationSink.Executor.<WaveletOperation, 
WaveletData>build(waveletData),
-            SilentOperationSink.VOID);
-      ReadOnlyWaveView waveView = new ReadOnlyWaveView(waveId);
-      waveView.addWavelet(wavelet);
-      
-      if (isConversational) {
-        ConversationView conversationView = 
WaveBasedConversationView.create(waveView, FakeIdGenerator.create());
-        WaveletBasedConversation.makeWaveletConversational(wavelet);
-        conversation = conversationView.getRoot();
-
-        conversation.addParticipant(author);
-      } else {
-        conversation = null;
-      }
-
-      waveViewData = WaveViewDataImpl.create(waveId, 
ImmutableList.of(waveletData, userWaveletData));
-    }
-
-    public void appendBlipWithText(String text) {
-      ConversationBlip blip = conversation.getRootThread().appendBlip();
-      LineContainers.appendToLastLine(blip.getContent(), 
XmlStringBuilder.createText(text));
-      TitleHelper.maybeFindAndSetImplicitTitle(blip.getContent());
-    }
-
-    public List<ObservableWaveletData> copyWaveletData() {
-      // This data object already has an op-based owner on top. Must copy it.
-      return ImmutableList.of(WaveletDataUtil.copyWavelet(waveletData),
-          WaveletDataUtil.copyWavelet(userWaveletData));
-    }
-
-    public WaveViewData copyViewData() {
-      return 
WaveViewDataImpl.create(waveViewData.getWaveId(),copyWaveletData());
-    }
-  }
-
   @Override
   protected void setUp() {
     MockitoAnnotations.initMocks(this);
     
-    conversationUtil = new ConversationUtil(idGenerator);
     when(operation.getParameter(ParamsProperty.QUERY)).thenReturn("in:inbox");
    
-    service = new SearchService(searchProvider, new 
ConversationUtil(idGenerator));
+    service = new SearchService(searchProvider);
   }
 
   public void testSearchWrapsSearchProvidersResult() throws 
InvalidRequestException {
-    TestingWaveletData data =
-        new TestingWaveletData(WAVE_ID, CONVERSATION_WAVELET_ID, PARTICIPANT, 
true);
-
-    data.conversation.addParticipant(OTHER_PARTICIPANT);
-    data.appendBlipWithText("title");
-    
-    when(searchProvider.search(USER, "in:inbox", 0, 10)).thenReturn(
-        Arrays.asList(data.copyViewData()));
+    String title = "title";
+    SearchResult.Digest digest =
+        new Digest(title, "", WAVE_ID.serialise(), 
ImmutableList.of(PARTICIPANT.getAddress(),
+            OTHER_PARTICIPANT.getAddress()), -1L, -1L, 1, 1);
+    String query = "in:inbox";
+    SearchResult searchResult = new SearchResult(query);
+    searchResult.addDigest(digest);
+    when(searchProvider.search(USER, query, 0, 10)).thenReturn(searchResult);
     service.execute(operation, context, USER);
 
     verify(context).constructResponse(
@@ -188,22 +95,6 @@ public class SearchServiceTest extends T
             PARTICIPANT, OTHER_PARTICIPANT), 1, 1)));
   }
 
-  public void testWaveletWithNoBlipsResultsInEmptyTitleAndNoBlips() {
-    TestingWaveletData data =
-        new TestingWaveletData(WAVE_ID, CONVERSATION_WAVELET_ID, PARTICIPANT, 
true);
-    ObservableWaveletData observableWaveletData = 
data.copyWaveletData().get(0);
-    ObservableWavelet wavelet = 
OpBasedWavelet.createReadOnly(observableWaveletData);
-    ObservableConversationView conversation = 
conversationUtil.buildConversation(wavelet);
-
-    SupplementedWave supplement = mock(SupplementedWave.class);
-    when(supplement.isUnread(any(ConversationBlip.class))).thenReturn(true);
-    
-    Digest digest = service.generateDigest(conversation, supplement, 
observableWaveletData);
-
-    assertEquals("", digest.getTitle());
-    assertEquals(digest.getBlipCount(), 0);
-  }
-
   // Note: this is really just testing that the SearchService does not 
over-step
   // its role and do additional filtering beyond that done by the search
   // provider. If the search provider starts filtering empty waves, then this
@@ -213,7 +104,13 @@ public class SearchServiceTest extends T
       new TestingWaveletData(WAVE_ID, CONVERSATION_WAVELET_ID, PARTICIPANT, 
false);
     final Collection<WaveViewData> providerResults = 
Arrays.asList(data.copyViewData());
 
-    when(searchProvider.search(USER, "in:inbox", 0, 
10)).thenReturn(providerResults);
+    String query = "in:inbox";
+    SearchResult.Digest digest =
+        new Digest("", "", WAVE_ID.serialise(), 
ImmutableList.of(PARTICIPANT.getAddress()), -1L,
+            -1L, 1, 1);
+    SearchResult searchResult = new SearchResult(query);
+    searchResult.addDigest(digest);
+    when(searchProvider.search(USER, query, 0, 10)).thenReturn(searchResult);
     service.execute(operation, context, USER);
 
     verify(context).constructResponse(
@@ -241,9 +138,11 @@ public class SearchServiceTest extends T
   }
 
   public void testDefaultFieldsMatchSpec() throws InvalidRequestException {
+    String query = "in:inbox";
+    when(searchProvider.search(USER, query, 0, 10)).thenReturn(new 
SearchResult(query));
     service.execute(operation, context, USER);
 
-    verify(searchProvider).search(USER, "in:inbox", 0, 10);
+    verify(searchProvider).search(USER, query, 0, 10);
   }
 
   public void testSearchThrowsOnMissingQueryParameter() {
@@ -286,7 +185,6 @@ public class SearchServiceTest extends T
 
         assertEquals(unreadCount, digest.getUnreadCount());
         assertEquals(blipCount, digest.getBlipCount());
-
         return true;
       }
 

Modified: 
incubator/wave/trunk/test/org/waveprotocol/box/server/waveserver/WaveMapTest.java
URL: 
http://svn.apache.org/viewvc/incubator/wave/trunk/test/org/waveprotocol/box/server/waveserver/WaveMapTest.java?rev=1206546&r1=1206545&r2=1206546&view=diff
==============================================================================
--- 
incubator/wave/trunk/test/org/waveprotocol/box/server/waveserver/WaveMapTest.java
 (original)
+++ 
incubator/wave/trunk/test/org/waveprotocol/box/server/waveserver/WaveMapTest.java
 Sat Nov 26 19:09:44 2011
@@ -21,10 +21,11 @@ import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.when;
 
 import com.google.common.collect.ImmutableSet;
+import com.google.common.collect.Lists;
 import com.google.common.collect.Ordering;
 import com.google.common.util.concurrent.Futures;
 import com.google.common.util.concurrent.MoreExecutors;
-import com.google.gwt.thirdparty.guava.common.collect.Lists;
+import com.google.wave.api.SearchResult;
 
 import junit.framework.TestCase;
 
@@ -34,10 +35,11 @@ import org.waveprotocol.box.common.Excep
 import org.waveprotocol.box.server.common.CoreWaveletOperationSerializer;
 import org.waveprotocol.box.server.persistence.PersistenceException;
 import org.waveprotocol.box.server.persistence.memory.MemoryDeltaStore;
+import org.waveprotocol.box.server.robots.util.ConversationUtil;
 import org.waveprotocol.wave.federation.Proto.ProtocolSignedDelta;
 import org.waveprotocol.wave.federation.Proto.ProtocolWaveletDelta;
+import org.waveprotocol.wave.model.id.IdGenerator;
 import org.waveprotocol.wave.model.id.IdURIEncoderDecoder;
-import org.waveprotocol.wave.model.id.IdUtil;
 import org.waveprotocol.wave.model.id.WaveId;
 import org.waveprotocol.wave.model.id.WaveletId;
 import org.waveprotocol.wave.model.id.WaveletName;
@@ -50,12 +52,9 @@ import org.waveprotocol.wave.model.versi
 import org.waveprotocol.wave.model.version.HashedVersionZeroFactoryImpl;
 import org.waveprotocol.wave.model.wave.ParticipantId;
 import org.waveprotocol.wave.model.wave.ParticipantIdUtil;
-import org.waveprotocol.wave.model.wave.data.ObservableWaveletData;
-import org.waveprotocol.wave.model.wave.data.WaveViewData;
 import org.waveprotocol.wave.util.escapers.jvm.JavaUrlCodec;
 
 import java.util.Arrays;
-import java.util.Collection;
 import java.util.Comparator;
 import java.util.concurrent.Executor;
 
@@ -80,93 +79,71 @@ public class WaveMapTest extends TestCas
   
 
   /** Sorts search result in ascending order by LMT. */
-  static final Comparator<WaveViewData> ASCENDING_DATE_COMPARATOR =
-      new Comparator<WaveViewData>() {
+  static final Comparator<SearchResult.Digest> ASCENDING_DATE_COMPARATOR =
+      new Comparator<SearchResult.Digest>() {
         @Override
-        public int compare(WaveViewData arg0, WaveViewData arg1) {
-          long lmt0 = computeLmt(arg0);
-          long lmt1 = computeLmt(arg1);
+        public int compare(SearchResult.Digest arg0, SearchResult.Digest arg1) 
{
+          long lmt0 = arg0.getLastModified();
+          long lmt1 = arg1.getLastModified();
           return Long.signum(lmt0 - lmt1);
         }
-
-        private long computeLmt(WaveViewData arg0) {
-          long lmt = -1;
-          for (ObservableWaveletData wavelet : arg0.getWavelets()) {
-            // Skip non conversational wavelets.
-            if (!IdUtil.isConversationalId(wavelet.getWaveletId())) {
-              continue;
-            }
-            lmt = lmt < wavelet.getLastModifiedTime() ? 
wavelet.getLastModifiedTime() : lmt;
-          }
-          return lmt;
-        }
       };
 
   /** Sorts search result in descending order by LMT. */
-  static final Comparator<WaveViewData> DESCENDING_DATE_COMPARATOR =
-      new Comparator<WaveViewData>() {
+  static final Comparator<SearchResult.Digest> DESCENDING_DATE_COMPARATOR =
+      new Comparator<SearchResult.Digest>() {
         @Override
-        public int compare(WaveViewData arg0, WaveViewData arg1) {
+        public int compare(SearchResult.Digest arg0, SearchResult.Digest arg1) 
{
           return -ASCENDING_DATE_COMPARATOR.compare(arg0, arg1);
         }
       };
-      
+
   /** Sorts search result in ascending order by creation time. */
-  static final Comparator<WaveViewData> ASC_CREATED_COMPARATOR = new 
Comparator<WaveViewData>() {
-    @Override
-    public int compare(WaveViewData arg0, WaveViewData arg1) {
-      long time0 = computeCreatedTime(arg0);
-      long time1 = computeCreatedTime(arg1);
-      return Long.signum(time0 - time1);
-    }
+  static final Comparator<SearchResult.Digest> ASC_CREATED_COMPARATOR =
+      new Comparator<SearchResult.Digest>() {
+        @Override
+        public int compare(SearchResult.Digest arg0, SearchResult.Digest arg1) 
{
+          long time0 = arg0.getCreated();
+          long time1 = arg1.getCreated();
+          return Long.signum(time0 - time1);
+        }
+      };
 
-    private long computeCreatedTime(WaveViewData arg0) {
-      long creationTime = -1;
-      for (ObservableWaveletData wavelet : arg0.getWavelets()) {
-        creationTime =
-            creationTime < wavelet.getCreationTime() ? 
wavelet.getCreationTime() : creationTime;
-      }
-      return creationTime;
-    }
-  };
-  
-  
   /** Sorts search result in descending order by creation time. */
-  static final Comparator<WaveViewData> DESC_CREATED_COMPARATOR = new 
Comparator<WaveViewData>() {
-    @Override
-    public int compare(WaveViewData arg0, WaveViewData arg1) {
-      return -ASC_CREATED_COMPARATOR.compare(arg0, arg1);
-    }
-  };
+  static final Comparator<SearchResult.Digest> DESC_CREATED_COMPARATOR =
+      new Comparator<SearchResult.Digest>() {
+        @Override
+        public int compare(SearchResult.Digest arg0, SearchResult.Digest arg1) 
{
+          return -ASC_CREATED_COMPARATOR.compare(arg0, arg1);
+        }
+      };
   
   /** Sorts search result in ascending order by author. */
-  static final Comparator<WaveViewData> ASC_CREATOR_COMPARATOR = new 
Comparator<WaveViewData>() {
-    @Override
-    public int compare(WaveViewData arg0, WaveViewData arg1) {
-      ParticipantId author0 = computeAuthor(arg0);
-      ParticipantId author1 = computeAuthor(arg1);
-      return author0.compareTo(author1);
-    }
+  static final Comparator<SearchResult.Digest> ASC_CREATOR_COMPARATOR =
+      new Comparator<SearchResult.Digest>() {
+        @Override
+        public int compare(SearchResult.Digest arg0, SearchResult.Digest arg1) 
{
+          ParticipantId author0 = computeAuthor(arg0);
+          ParticipantId author1 = computeAuthor(arg1);
+          return author0.compareTo(author1);
+        }
 
-    private ParticipantId computeAuthor(WaveViewData wave) {
-      ParticipantId author = null;
-      for (ObservableWaveletData wavelet : wave.getWavelets()) {
-        if (IdUtil.isConversationRootWaveletId(wavelet.getWaveletId())) {
-          author = wavelet.getCreator();
+        private ParticipantId computeAuthor(SearchResult.Digest digest) {
+          ParticipantId author = null;
+          author = ParticipantId.ofUnsafe(digest.getParticipants().get(0));
+          assert author != null : "Cannot find author for the wave: " + 
digest.getWaveId();
+          return author;
         }
-      }
-      assert author != null : "Cannot find author for the wave: " + 
wave.getWaveId().serialise();
-      return author;
-    }
-  };
+      };
   
   /** Sorts search result in descending order by author. */
-  static final Comparator<WaveViewData> DESC_CREATOR_COMPARATOR = new 
Comparator<WaveViewData>() {
-    @Override
-    public int compare(WaveViewData arg0, WaveViewData arg1) {
-      return -ASC_CREATOR_COMPARATOR.compare(arg0, arg1);
-    }
-  };
+  static final Comparator<SearchResult.Digest> DESC_CREATOR_COMPARATOR =
+      new Comparator<SearchResult.Digest>() {
+        @Override
+        public int compare(SearchResult.Digest arg0, SearchResult.Digest arg1) 
{
+          return -ASC_CREATOR_COMPARATOR.compare(arg0, arg1);
+        }
+      };
 
   private static WaveletOperation addParticipantToWavelet(ParticipantId user) {
     return new AddParticipant(CONTEXT, user);
@@ -174,10 +151,14 @@ public class WaveMapTest extends TestCas
 
   @Mock private WaveletNotificationDispatcher notifiee;
   @Mock private RemoteWaveletContainer.Factory remoteWaveletContainerFactory;
+  
+  @Mock private IdGenerator idGenerator;
 
   private DeltaAndSnapshotStore waveletStore;
   private WaveMap waveMap;
-
+  private ConversationUtil conversationUtil;
+  private WaveDigester digester;
+  
   @Override
   protected void setUp() throws Exception {
     MockitoAnnotations.initMocks(this);
@@ -201,10 +182,12 @@ public class WaveMapTest extends TestCas
           }
         };
 
+    conversationUtil = new ConversationUtil(idGenerator);
+    digester = new WaveDigester(conversationUtil);
     waveletStore = mock(DeltaAndSnapshotStore.class);
     waveMap =
         new WaveMap(waveletStore, notifiee, notifiee, 
localWaveletContainerFactory,
-            remoteWaveletContainerFactory, "example.com");
+            remoteWaveletContainerFactory, "example.com", digester);
   }
 
   public void testWaveMapStartsEmpty() throws WaveServerException {
@@ -241,25 +224,25 @@ public class WaveMapTest extends TestCas
   }
 
   public void testSearchEmptyInboxReturnsNothing() {
-    Collection<WaveViewData> results = waveMap.search(USER1, "in:inbox", 0, 
20);
+    SearchResult results = waveMap.search(USER1, "in:inbox", 0, 20);
 
-    assertEquals(0, results.size());
+    assertEquals(0, results.getNumResults());
   }
 
   public void testSearchInboxReturnsWaveWithExplicitParticipant() throws 
Exception {
     submitDeltaToNewWavelet(WAVELET_NAME, USER1, 
addParticipantToWavelet(USER2));
 
-    Collection<WaveViewData> results = waveMap.search(USER2, "in:inbox", 0, 
20);
+    SearchResult results = waveMap.search(USER2, "in:inbox", 0, 20);
 
-    assertEquals(1, results.size());
-    assertEquals(WAVELET_NAME.waveId, results.iterator().next().getWaveId());
+    assertEquals(1, results.getNumResults());
+    assertEquals(WAVELET_NAME.waveId.serialise(), 
results.getDigests().get(0).getWaveId());
   }
 
   public void testSearchInboxDoesNotReturnWaveWithoutUser() throws Exception {
     submitDeltaToNewWavelet(WAVELET_NAME, USER1, 
addParticipantToWavelet(USER1));
 
-    Collection<WaveViewData> results = waveMap.search(USER2, "in:inbox", 0, 
20);
-    assertEquals(0, results.size());
+    SearchResult results = waveMap.search(USER2, "in:inbox", 0, 20);
+    assertEquals(0, results.getNumResults());
   }
   
   public void testSearchWaveReturnsWaveWithImplicitParticipant() throws 
Exception {
@@ -274,9 +257,9 @@ public class WaveMapTest extends TestCas
     // Explicit participant in this wave.
     submitDeltaToNewWavelet(waveletName, USER1, 
addParticipantToWavelet(USER2));
 
-    Collection<WaveViewData> results = waveMap.search(USER2, "", 0, 20);
+    SearchResult results = waveMap.search(USER2, "", 0, 20);
     // Should return both waves.
-    assertEquals(2, results.size());
+    assertEquals(2, results.getNumResults());
   }
 
   public void testSearchAllReturnsWavesOnlyWithSharedDomainUser() throws 
Exception {
@@ -286,8 +269,8 @@ public class WaveMapTest extends TestCas
     waveletName = WaveletName.of(WaveId.of(DOMAIN, String.valueOf(2)), 
WAVELET_ID);
     submitDeltaToNewWavelet(waveletName, USER1, 
addParticipantToWavelet(USER2));
     
-    Collection<WaveViewData> results = waveMap.search(USER2, "", 0, 20);
-    assertEquals(1, results.size());
+    SearchResult results = waveMap.search(USER2, "", 0, 20);
+    assertEquals(1, results.getNumResults());
   }
 
   public void testSearchLimitEnforced() throws Exception {
@@ -296,9 +279,9 @@ public class WaveMapTest extends TestCas
       submitDeltaToNewWavelet(name, USER1, addParticipantToWavelet(USER1));
     }
 
-    Collection<WaveViewData> results = waveMap.search(USER1, "in:inbox", 0, 5);
+    SearchResult results = waveMap.search(USER1, "in:inbox", 0, 5);
 
-    assertEquals(5, results.size());
+    assertEquals(5, results.getNumResults());
   }
 
   public void testSearchIndexWorks() throws Exception {
@@ -315,9 +298,10 @@ public class WaveMapTest extends TestCas
     int[] saw_wave = new int[10];
 
     for (int i = 0; i < 10; i++) {
-      Collection<WaveViewData> results = waveMap.search(USER1, "in:inbox", i, 
1);
-      assertEquals(1, results.size());
-      int index = 
Integer.parseInt(results.iterator().next().getWaveId().getId());
+      SearchResult results = waveMap.search(USER1, "in:inbox", i, 1);
+      assertEquals(1, results.getNumResults());
+      WaveId waveId = 
WaveId.deserialise(results.getDigests().get(0).getWaveId());
+      int index = Integer.parseInt(waveId.getId());
       saw_wave[index]++;
     }
 
@@ -332,9 +316,9 @@ public class WaveMapTest extends TestCas
       WaveletName name = WaveletName.of(WaveId.of(DOMAIN, String.valueOf(i)), 
WAVELET_ID);
       submitDeltaToNewWavelet(name, USER1, addParticipantToWavelet(USER1));
     }
-    Collection<WaveViewData> results = waveMap.search(USER1, "in:inbox 
orderby:dateasc", 0, 10);
-    Ordering<WaveViewData> ascOrdering = 
Ordering.from(ASCENDING_DATE_COMPARATOR);
-    assertTrue(ascOrdering.isOrdered(results));
+    SearchResult results = waveMap.search(USER1, "in:inbox orderby:dateasc", 
0, 10);
+    Ordering<SearchResult.Digest> ascOrdering = 
Ordering.from(ASCENDING_DATE_COMPARATOR);
+    assertTrue(ascOrdering.isOrdered(results.getDigests()));
   }
   
   public void testSearchOrderByDescWorks() throws Exception {
@@ -342,9 +326,9 @@ public class WaveMapTest extends TestCas
       WaveletName name = WaveletName.of(WaveId.of(DOMAIN, String.valueOf(i)), 
WAVELET_ID);
       submitDeltaToNewWavelet(name, USER1, addParticipantToWavelet(USER1));
     }
-    Collection<WaveViewData> results = waveMap.search(USER1, "in:inbox 
orderby:datedesc", 0, 10);
-    Ordering<WaveViewData> descOrdering = 
Ordering.from(DESCENDING_DATE_COMPARATOR);
-    assertTrue(descOrdering.isOrdered(results));
+    SearchResult results = waveMap.search(USER1, "in:inbox orderby:datedesc", 
0, 10);
+    Ordering<SearchResult.Digest> descOrdering = 
Ordering.from(DESCENDING_DATE_COMPARATOR);
+    assertTrue(descOrdering.isOrdered(results.getDigests()));
   }
   
   public void testSearchOrderByCreatedAscWorks() throws Exception {
@@ -352,9 +336,9 @@ public class WaveMapTest extends TestCas
       WaveletName name = WaveletName.of(WaveId.of(DOMAIN, String.valueOf(i)), 
WAVELET_ID);
       submitDeltaToNewWavelet(name, USER1, addParticipantToWavelet(USER1));
     }
-    Collection<WaveViewData> results = waveMap.search(USER1, "in:inbox 
orderby:createdasc", 0, 10);
-    Ordering<WaveViewData> ascOrdering = Ordering.from(ASC_CREATED_COMPARATOR);
-    assertTrue(ascOrdering.isOrdered(results));
+    SearchResult results = waveMap.search(USER1, "in:inbox 
orderby:createdasc", 0, 10);
+    Ordering<SearchResult.Digest> ascOrdering = 
Ordering.from(ASC_CREATED_COMPARATOR);
+    assertTrue(ascOrdering.isOrdered(results.getDigests()));
   }
   
   public void testSearchOrderByCreatedDescWorks() throws Exception {
@@ -362,9 +346,9 @@ public class WaveMapTest extends TestCas
       WaveletName name = WaveletName.of(WaveId.of(DOMAIN, String.valueOf(i)), 
WAVELET_ID);
       submitDeltaToNewWavelet(name, USER1, addParticipantToWavelet(USER1));
     }
-    Collection<WaveViewData> results = waveMap.search(USER1, "in:inbox 
orderby:createddesc", 0, 10);
-    Ordering<WaveViewData> descOrdering = 
Ordering.from(DESC_CREATED_COMPARATOR);
-    assertTrue(descOrdering.isOrdered(results));
+    SearchResult results = waveMap.search(USER1, "in:inbox 
orderby:createddesc", 0, 10);
+    Ordering<SearchResult.Digest> descOrdering = 
Ordering.from(DESC_CREATED_COMPARATOR);
+    assertTrue(descOrdering.isOrdered(results.getDigests()));
   }
   
   public void testSearchOrderByAuthorAscWithCompundingWorks() throws Exception 
{
@@ -379,17 +363,19 @@ public class WaveMapTest extends TestCas
         submitDeltaToNewWavelet(name, USER2, addParticipantToWavelet(USER2));
       }
     }
-    Collection<WaveViewData> resultsAsc =
+    SearchResult resultsAsc =
         waveMap.search(USER2, "in:inbox orderby:creatorasc 
orderby:createddesc", 0, 10);
-    assertEquals(10, resultsAsc.size());
-    Ordering<WaveViewData> ascAuthorOrdering = 
Ordering.from(ASC_CREATOR_COMPARATOR);
-    assertTrue(ascAuthorOrdering.isOrdered(resultsAsc));
-    Ordering<WaveViewData> descCreatedOrdering = 
Ordering.from(DESC_CREATED_COMPARATOR);
+    assertEquals(10, resultsAsc.getNumResults());
+    Ordering<SearchResult.Digest> ascAuthorOrdering = 
Ordering.from(ASC_CREATOR_COMPARATOR);
+    assertTrue(ascAuthorOrdering.isOrdered(resultsAsc.getDigests()));
+    Ordering<SearchResult.Digest> descCreatedOrdering = 
Ordering.from(DESC_CREATED_COMPARATOR);
     // The whole list should not be ordered by creation time.
-    assertFalse(descCreatedOrdering.isOrdered(resultsAsc));
+    assertFalse(descCreatedOrdering.isOrdered(resultsAsc.getDigests()));
     // Each sublist should be ordered by creation time.
-    
assertTrue(descCreatedOrdering.isOrdered(Lists.newArrayList(resultsAsc).subList(0,
 2)));
-    
assertTrue(descCreatedOrdering.isOrdered(Lists.newArrayList(resultsAsc).subList(2,
 10)));
+    
assertTrue(descCreatedOrdering.isOrdered(Lists.newArrayList(resultsAsc.getDigests()).subList(0,
+        2)));
+    
assertTrue(descCreatedOrdering.isOrdered(Lists.newArrayList(resultsAsc.getDigests()).subList(2,
+        10)));
   }
   
   public void testSearchOrderByAuthorDescWorks() throws Exception {
@@ -404,11 +390,11 @@ public class WaveMapTest extends TestCas
         submitDeltaToNewWavelet(name, USER2, addParticipantToWavelet(USER2));
       }
     }
-    Collection<WaveViewData> resultsAsc =
+    SearchResult resultsAsc =
         waveMap.search(USER2, "in:inbox orderby:creatordesc", 0, 10);
-    assertEquals(10, resultsAsc.size());
-    Ordering<WaveViewData> descAuthorOrdering = 
Ordering.from(DESC_CREATOR_COMPARATOR);
-    assertTrue(descAuthorOrdering.isOrdered(resultsAsc));
+    assertEquals(10, resultsAsc.getNumResults());
+    Ordering<SearchResult.Digest> descAuthorOrdering = 
Ordering.from(DESC_CREATOR_COMPARATOR);
+    assertTrue(descAuthorOrdering.isOrdered(resultsAsc.getDigests()));
   }
   
   public void testSearchFilterByWithWorks() throws Exception {
@@ -423,11 +409,11 @@ public class WaveMapTest extends TestCas
         submitDeltaToNewWavelet(name, USER1, addParticipantToWavelet(USER1));
       }
     }
-    Collection<WaveViewData> results =
+    SearchResult results =
         waveMap.search(USER1, "in:inbox with:" + USER2.getAddress(), 0, 10);
-    assertEquals(2, results.size());
+    assertEquals(2, results.getNumResults());
     results = waveMap.search(USER1, "in:inbox with:" + USER1.getAddress(), 0, 
10);
-    assertEquals(10, results.size());
+    assertEquals(10, results.getNumResults());
   }
   
   /**
@@ -436,9 +422,9 @@ public class WaveMapTest extends TestCas
   public void testInvalidWithSearchParam() throws Exception {
     WaveletName name = WaveletName.of(WAVE_ID, WAVELET_ID);
     submitDeltaToNewWavelet(name, USER1, addParticipantToWavelet(USER1));
-    Collection<WaveViewData> results =
+    SearchResult results =
         waveMap.search(USER1, "in:inbox with@^^^@:" + USER1.getAddress(), 0, 
10);
-    assertEquals(0, results.size());
+    assertEquals(0, results.getNumResults());
   }
   
   public void testInvalidOrderByParam() throws Exception {
@@ -446,9 +432,9 @@ public class WaveMapTest extends TestCas
       WaveletName name = WaveletName.of(WaveId.of(DOMAIN, String.valueOf(i)), 
WAVELET_ID);
       submitDeltaToNewWavelet(name, USER1, addParticipantToWavelet(USER1));
     }
-    Collection<WaveViewData> results =
+    SearchResult results =
         waveMap.search(USER1, "in:inbox orderby:createddescCCC", 0, 10);
-    assertEquals(0, results.size());
+    assertEquals(0, results.getNumResults());
   }
   
   public void testSearchFilterByCreatorWorks() throws Exception {
@@ -463,15 +449,15 @@ public class WaveMapTest extends TestCas
         submitDeltaToNewWavelet(name, USER1, addParticipantToWavelet(USER1));
       }
     }
-    Collection<WaveViewData> results =
+    SearchResult results =
         waveMap.search(USER1, "in:inbox creator:" + USER2.getAddress(), 0, 10);
-    assertEquals(2, results.size());
+    assertEquals(2, results.getNumResults());
     results = waveMap.search(USER1, "in:inbox creator:" + USER1.getAddress(), 
0, 10);
-    assertEquals(8, results.size());
+    assertEquals(8, results.getNumResults());
     results =
         waveMap.search(USER1,
             "in:inbox creator:" + USER1.getAddress() + " creator:" + 
USER2.getAddress(), 0, 10);
-    assertEquals(0, results.size());
+    assertEquals(0, results.getNumResults());
   }
 
 

Modified: 
incubator/wave/trunk/test/org/waveprotocol/box/server/waveserver/WaveServerTest.java
URL: 
http://svn.apache.org/viewvc/incubator/wave/trunk/test/org/waveprotocol/box/server/waveserver/WaveServerTest.java?rev=1206546&r1=1206545&r2=1206546&view=diff
==============================================================================
--- 
incubator/wave/trunk/test/org/waveprotocol/box/server/waveserver/WaveServerTest.java
 (original)
+++ 
incubator/wave/trunk/test/org/waveprotocol/box/server/waveserver/WaveServerTest.java
 Sat Nov 26 19:09:44 2011
@@ -33,12 +33,14 @@ import org.mockito.MockitoAnnotations;
 import org.waveprotocol.box.common.ExceptionalIterator;
 import org.waveprotocol.box.server.common.CoreWaveletOperationSerializer;
 import org.waveprotocol.box.server.persistence.memory.MemoryDeltaStore;
+import org.waveprotocol.box.server.robots.util.ConversationUtil;
 import org.waveprotocol.box.server.waveserver.LocalWaveletContainer.Factory;
 import 
org.waveprotocol.box.server.waveserver.WaveletProvider.SubmitRequestListener;
 import org.waveprotocol.wave.federation.Proto.ProtocolSignature;
 import org.waveprotocol.wave.federation.Proto.ProtocolSignedDelta;
 import org.waveprotocol.wave.federation.Proto.ProtocolWaveletDelta;
 import org.waveprotocol.wave.federation.WaveletFederationProvider;
+import org.waveprotocol.wave.model.id.IdGenerator;
 import org.waveprotocol.wave.model.id.IdURIEncoderDecoder;
 import org.waveprotocol.wave.model.id.WaveId;
 import org.waveprotocol.wave.model.id.WaveletId;
@@ -83,6 +85,11 @@ public class WaveServerTest extends Test
   @Mock private WaveletFederationProvider federationRemote;
   @Mock private WaveletNotificationDispatcher notifiee;
   @Mock private RemoteWaveletContainer.Factory remoteWaveletContainerFactory;
+  
+  @Mock private IdGenerator idGenerator;
+
+  private ConversationUtil conversationUtil;
+  private WaveDigester digester;
 
   private CertificateManager certificateManager;
   private DeltaAndSnapshotStore waveletStore;
@@ -112,9 +119,11 @@ public class WaveServerTest extends Test
     };
 
     waveletStore = new DeltaStoreBasedSnapshotStore(deltaStore);
+    conversationUtil = new ConversationUtil(idGenerator);
+    digester = new WaveDigester(conversationUtil);
     waveMap =
         new WaveMap(waveletStore, notifiee, notifiee, 
localWaveletContainerFactory,
-            remoteWaveletContainerFactory, "example.com");
+            remoteWaveletContainerFactory, "example.com", digester);
     waveServer =
         new WaveServerImpl(MoreExecutors.sameThreadExecutor(), 
certificateManager,
             federationRemote, waveMap);
@@ -133,10 +142,8 @@ public class WaveServerTest extends Test
 
     verify(notifiee).waveletUpdate(Matchers.<ReadableWaveletData>any(),
         Matchers.<ImmutableList<WaveletDeltaRecord>>any(), 
eq(ImmutableSet.of(DOMAIN)));
-    // TODO(anorth): Re-enable this check when WaveletContainerImpl injects an
-    // executor rather than using its own.
-//    verify(notifiee).waveletCommitted(eq(WAVELET_NAME), 
Matchers.<HashedVersion>any(),
-//        eq(ImmutableSet.of(DOMAIN)));
+    verify(notifiee).waveletCommitted(eq(WAVELET_NAME), 
Matchers.<HashedVersion>any(),
+        eq(ImmutableSet.of(DOMAIN)));
   }
 
   private void submitDeltaToNewWavelet(WaveletName name, ParticipantId user,


Reply via email to