コード例 #1
0
 @Override
 public Collection<WaveViewData> search(
     ParticipantId user, String query, int startAt, int numResults) {
   LOG.fine(
       "Search query '"
           + query
           + "' from user: "******" ["
           + startAt
           + ", "
           + (startAt + numResults - 1)
           + "]");
   Map<QueryHelper.TokenQueryType, Set<String>> queryParams = null;
   try {
     queryParams = queryHelper.parseQuery(query);
   } catch (QueryHelper.InvalidQueryException e1) {
     // Invalid query param - stop and return empty search results.
     LOG.warning("Invalid Query. " + e1.getMessage());
     return Collections.emptyList();
   }
   List<ParticipantId> withParticipantIds = null;
   List<ParticipantId> creatorParticipantIds = null;
   try {
     String localDomain = user.getDomain();
     // Build and validate.
     withParticipantIds =
         QueryHelper.buildValidatedParticipantIds(
             queryParams, QueryHelper.TokenQueryType.WITH, localDomain);
     creatorParticipantIds =
         QueryHelper.buildValidatedParticipantIds(
             queryParams, QueryHelper.TokenQueryType.CREATOR, localDomain);
   } catch (InvalidParticipantAddress e) {
     // Invalid address - stop and return empty search results.
     LOG.warning("Invalid participantId: " + e.getAddress() + " in query: " + query);
     return Collections.emptyList();
   }
   // Maybe should be changed in case other folders in addition to 'inbox' are added.
   boolean isAllQuery = !queryParams.containsKey(QueryHelper.TokenQueryType.IN);
   // Must use a map with stable ordering, since indices are meaningful.
   Map<WaveId, WaveViewData> results = Maps.newLinkedHashMap();
   for (Map.Entry<WaveId, Wave> entry : waves.entrySet()) {
     WaveId waveId = entry.getKey();
     Wave wave = entry.getValue();
     WaveViewData view = null; // Copy of the wave built up for search hits.
     for (WaveletContainer c : wave) {
       // TODO (Yuri Z.) This loop collects all the wavelets that match the
       // query, so the view is determined by the query. Instead we should
       // look at the user's wave view and determine if the view matches the query.
       ParticipantId sharedDomainParticipantId = c.getSharedDomainParticipant();
       try {
         // TODO (Yuri Z.) Need to explore how to avoid this copy, e.g., by
         // moving parts of the matches() logic into a WaveletContainer method.
         ObservableWaveletData wavelet = c.copyWaveletData();
         // Only filtering by participants is implemented for now.
         if (!matches(
             wavelet,
             user,
             sharedDomainParticipantId,
             withParticipantIds,
             creatorParticipantIds,
             isAllQuery)) {
           continue;
         }
         if (view == null) {
           view = WaveViewDataImpl.create(waveId);
         }
         // Just keep adding all the relevant wavelets in this wave.
         view.addWavelet(wavelet);
       } catch (WaveletStateException e) {
         LOG.warning("Failed to access wavelet " + c.getWaveletName(), e);
       }
     }
     // Filter out waves without conversational root wavelet from search result.
     if (WaveletDataUtil.hasConversationalRootWavelet(view)) {
       results.put(waveId, view);
     }
   }
   List<WaveViewData> searchResultslist = null;
   int searchResultSize = results.values().size();
   // Check if we have enough results to return.
   if (searchResultSize < startAt) {
     searchResultslist = Collections.emptyList();
   } else {
     int endAt = Math.min(startAt + numResults, searchResultSize);
     searchResultslist =
         QueryHelper.computeSorter(queryParams)
             .sortedCopy(results.values())
             .subList(startAt, endAt);
   }
   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);
 }