WAVE-311 Refactors some more, ensures Solr search result include user data 
wavelet.


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

Branch: refs/heads/master
Commit: deb185440a815fe6149a7083cac924d499d46e93
Parents: d566b91
Author: Yuri Zelikov <[email protected]>
Authored: Tue Apr 15 21:59:14 2014 +0300
Committer: Yuri Zelikov <[email protected]>
Committed: Wed Aug 27 19:17:55 2014 +0300

----------------------------------------------------------------------
 .../box/server/robots/OperationContextImpl.java | 26 +++++++-------
 .../box/server/robots/util/OperationUtil.java   | 37 +++++++-------------
 .../waveserver/AbstractSearchProviderImpl.java  | 12 ++++---
 .../waveserver/SimpleSearchProviderImpl.java    | 12 +++----
 .../waveserver/SolrSearchProviderImpl.java      | 20 +++++++++--
 .../server/waveserver/SolrWaveIndexerImpl.java  | 13 ++++---
 src/org/waveprotocol/wave/model/id/IdUtil.java  | 14 +++++++-
 7 files changed, 76 insertions(+), 58 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-wave/blob/deb18544/src/org/waveprotocol/box/server/robots/OperationContextImpl.java
----------------------------------------------------------------------
diff --git a/src/org/waveprotocol/box/server/robots/OperationContextImpl.java 
b/src/org/waveprotocol/box/server/robots/OperationContextImpl.java
index 7e4809e..03874ea 100644
--- a/src/org/waveprotocol/box/server/robots/OperationContextImpl.java
+++ b/src/org/waveprotocol/box/server/robots/OperationContextImpl.java
@@ -19,7 +19,6 @@
 
 package org.waveprotocol.box.server.robots;
 
-import static 
org.waveprotocol.box.server.robots.util.OperationUtil.buildUserDataWaveletId;
 import static 
org.waveprotocol.box.server.robots.util.RobotsUtil.createEmptyRobotWavelet;
 
 import com.google.common.base.Preconditions;
@@ -37,27 +36,28 @@ import com.google.wave.api.event.EventSerializer;
 import com.google.wave.api.event.EventType;
 import com.google.wave.api.event.OperationErrorEvent;
 
+import org.waveprotocol.box.common.Receiver;
 import org.waveprotocol.box.server.frontend.CommittedWaveletSnapshot;
 import org.waveprotocol.box.server.robots.util.ConversationUtil;
 import org.waveprotocol.box.server.robots.util.OperationUtil;
 import org.waveprotocol.box.server.waveserver.WaveServerException;
 import org.waveprotocol.box.server.waveserver.WaveletProvider;
-import org.waveprotocol.box.common.Receiver;
 import org.waveprotocol.wave.model.conversation.Conversation;
 import org.waveprotocol.wave.model.conversation.ConversationBlip;
 import org.waveprotocol.wave.model.conversation.ObservableConversationView;
+import org.waveprotocol.wave.model.id.IdUtil;
+import org.waveprotocol.wave.model.id.InvalidIdException;
+import org.waveprotocol.wave.model.id.WaveId;
+import org.waveprotocol.wave.model.id.WaveletId;
+import org.waveprotocol.wave.model.id.WaveletName;
+import org.waveprotocol.wave.model.operation.wave.TransformedWaveletDelta;
 import org.waveprotocol.wave.model.schema.SchemaCollection;
+import org.waveprotocol.wave.model.version.HashedVersion;
 import org.waveprotocol.wave.model.wave.ParticipantId;
 import org.waveprotocol.wave.model.wave.data.ObservableWaveletData;
 import 
org.waveprotocol.wave.model.wave.data.impl.ObservablePluggableMutableDocument;
 import org.waveprotocol.wave.model.wave.data.impl.WaveletDataImpl;
 import org.waveprotocol.wave.model.wave.opbased.OpBasedWavelet;
-import org.waveprotocol.wave.model.operation.wave.TransformedWaveletDelta;
-import org.waveprotocol.wave.model.id.InvalidIdException;
-import org.waveprotocol.wave.model.id.WaveId;
-import org.waveprotocol.wave.model.id.WaveletId;
-import org.waveprotocol.wave.model.id.WaveletName;
-import org.waveprotocol.wave.model.version.HashedVersion;
 import org.waveprotocol.wave.util.logging.Log;
 
 import java.util.Collections;
@@ -111,7 +111,7 @@ public class OperationContextImpl implements 
OperationContext, OperationResults
   private final Map<WaveletName, WaveletName> tempWaveletNameMap = 
Maps.newHashMap();
   /** Caches {@link ObservableConversationView}s */
   private final Map<WaveletName, Map<ParticipantId, 
ObservableConversationView>>
-      openedConversations;
+  openedConversations;
 
   /** Used to create conversations. */
   private final ConversationUtil conversationUtil;
@@ -225,7 +225,7 @@ public class OperationContextImpl implements 
OperationContext, OperationResults
       // Open a wavelet from the server
       CommittedWaveletSnapshot snapshot = getWaveletSnapshot(waveletName, 
participant);
       if (snapshot == null) {
-        if (waveletName.waveletId.equals(buildUserDataWaveletId(participant))) 
{
+        if 
(waveletName.waveletId.equals(IdUtil.buildUserDataWaveletId(participant))) {
           // Usually the user data is created by the web client whenever user
           // opens a wavelet for the first time. However, if the wavelet is
           // fetched for the first time with Robot/Data API - user data should 
be
@@ -234,7 +234,7 @@ public class OperationContextImpl implements 
OperationContext, OperationResults
         } else {
           throw new InvalidRequestException("Wavelet " + waveletName + " 
couldn't be retrieved");
         }
-        
+
       } else {
         ObservableWaveletData obsWavelet = FACTORY.create(snapshot.snapshot);
         wavelet = new RobotWaveletData(obsWavelet, snapshot.committedVersion);
@@ -362,7 +362,7 @@ public class OperationContextImpl implements 
OperationContext, OperationResults
 
   @Override
   public CommittedWaveletSnapshot getWaveletSnapshot(WaveletName waveletName, 
ParticipantId participant)
-    throws InvalidRequestException {
+      throws InvalidRequestException {
     try {
       if (!waveletProvider.checkAccessPermission(waveletName, participant)) {
         throw new InvalidRequestException("Access rejected");
@@ -377,7 +377,7 @@ public class OperationContextImpl implements 
OperationContext, OperationResults
   @Override
   public void getDeltas(WaveletName waveletName, ParticipantId participant,
       HashedVersion fromVersion, HashedVersion toVersion, 
Receiver<TransformedWaveletDelta> receiver)
-      throws InvalidRequestException {
+          throws InvalidRequestException {
     try {
       if (!waveletProvider.checkAccessPermission(waveletName, participant)) {
         throw new InvalidRequestException("Access rejected");

http://git-wip-us.apache.org/repos/asf/incubator-wave/blob/deb18544/src/org/waveprotocol/box/server/robots/util/OperationUtil.java
----------------------------------------------------------------------
diff --git a/src/org/waveprotocol/box/server/robots/util/OperationUtil.java 
b/src/org/waveprotocol/box/server/robots/util/OperationUtil.java
index 5a13938..18f106d 100644
--- a/src/org/waveprotocol/box/server/robots/util/OperationUtil.java
+++ b/src/org/waveprotocol/box/server/robots/util/OperationUtil.java
@@ -38,7 +38,6 @@ import org.waveprotocol.box.server.waveserver.WaveletProvider;
 import 
org.waveprotocol.box.server.waveserver.WaveletProvider.SubmitRequestListener;
 import org.waveprotocol.wave.federation.Proto.ProtocolWaveletDelta;
 import org.waveprotocol.wave.model.conversation.ConversationView;
-import org.waveprotocol.wave.model.id.IdConstants;
 import org.waveprotocol.wave.model.id.IdUtil;
 import org.waveprotocol.wave.model.id.InvalidIdException;
 import org.waveprotocol.wave.model.id.WaveId;
@@ -85,7 +84,7 @@ public class OperationUtil {
       throws InvalidRequestException {
     Object parameter = operation.getParameter(property);
     Class<T> clazz = (Class<T>) property.clazz();
-    if (parameter == null || !clazz.isInstance(parameter)) {
+    if ((parameter == null) || !clazz.isInstance(parameter)) {
       throw new InvalidRequestException("property " + property + " not found", 
operation);
     }
     return clazz.cast(parameter);
@@ -120,7 +119,7 @@ public class OperationUtil {
       OperationRequest operation, ParamsProperty property, T defaultValue) {
     Object parameter = operation.getParameter(property);
     Class<T> clazz = (Class<T>) property.clazz();
-    if (parameter != null && clazz.isInstance(parameter)) {
+    if ((parameter != null) && clazz.isInstance(parameter)) {
       return clazz.cast(parameter);
     }
     return defaultValue;
@@ -168,7 +167,7 @@ public class OperationUtil {
    * Executes an {@link OperationRequest}. If the operation throws an
    * {@link InvalidRequestException} this exception will be used to construct 
an
    * error response in the {@link OperationContext}.
-   * 
+   *
    * @param operation the operation to be executed. If the operation contains
    *        {@link ParamsProperty.PROXYING_FOR} - then it will be taken in
    *        account.
@@ -210,11 +209,11 @@ public class OperationUtil {
       }
     }
   }
-  
-  
+
+
   /**
    * Appends proxyFor to the participant address.
-   * 
+   *
    * @param proxyFor the proxyFor.
    * @param participant the participant to apply the proxyFor.
    * @return new participant instance in the format
@@ -242,7 +241,7 @@ public class OperationUtil {
   /**
    * Computes participant ID using optional {@link ParamsProperty.PROXYING_FOR}
    * parameter.
-   * 
+   *
    * @param operation the operation to be executed.
    * @param participant the base participant id.
    * @return new participant instance in the format
@@ -260,24 +259,14 @@ public class OperationUtil {
     } catch (InvalidParticipantAddress e) {
       throw new InvalidRequestException(
           participant.getAddress()
-              + (proxyAddress != null ? "+" + proxyAddress : ""
-                  + " is not a valid participant address"), operation);
+          + (proxyAddress != null ? "+" + proxyAddress : ""
+              + " is not a valid participant address"), operation);
     }
   }
-  
-  /**
-   * Builds user data wavelet id.
-   */
-  public static WaveletId buildUserDataWaveletId(ParticipantId participant) {
-    WaveletId udwId =
-      WaveletId.of(participant.getDomain(),
-          IdUtil.join(IdConstants.USER_DATA_WAVELET_PREFIX, 
participant.getAddress()));
-    return udwId;
-  }
-  
+
   /**
    * Builds the supplement model for a wave.
-   * 
+   *
    * @param operation the operation.
    * @param context the operation context.
    * @param participant the viewer.
@@ -292,7 +281,7 @@ public class OperationUtil {
 
     // TODO (Yuri Z.) Find a way to obtain an instance of IdGenerator and use 
it
     // to create udwId.
-    WaveletId udwId = buildUserDataWaveletId(participant);
+    WaveletId udwId = IdUtil.buildUserDataWaveletId(participant);
     String waveIdStr = OperationUtil.getRequiredParameter(operation, 
ParamsProperty.WAVE_ID);
     WaveId waveId = null;
     try {
@@ -305,7 +294,7 @@ public class OperationUtil {
     PrimitiveSupplement udwState = WaveletBasedSupplement.create(udw);
 
     SupplementedWave supplement =
-      SupplementedWaveImpl.create(udwState, conversationView, participant, 
DefaultFollow.ALWAYS);
+        SupplementedWaveImpl.create(udwState, conversationView, participant, 
DefaultFollow.ALWAYS);
     return supplement;
   }
 

http://git-wip-us.apache.org/repos/asf/incubator-wave/blob/deb18544/src/org/waveprotocol/box/server/waveserver/AbstractSearchProviderImpl.java
----------------------------------------------------------------------
diff --git 
a/src/org/waveprotocol/box/server/waveserver/AbstractSearchProviderImpl.java 
b/src/org/waveprotocol/box/server/waveserver/AbstractSearchProviderImpl.java
index f3d18c2..7d55812 100644
--- a/src/org/waveprotocol/box/server/waveserver/AbstractSearchProviderImpl.java
+++ b/src/org/waveprotocol/box/server/waveserver/AbstractSearchProviderImpl.java
@@ -20,9 +20,9 @@
 package org.waveprotocol.box.server.waveserver;
 
 import com.google.common.base.Function;
+import com.google.common.collect.LinkedHashMultimap;
 import com.google.common.collect.Lists;
 import com.google.common.collect.Maps;
-import com.google.common.collect.Multimap;
 
 import org.waveprotocol.box.server.util.WaveletDataUtil;
 import org.waveprotocol.wave.model.id.IdUtil;
@@ -37,10 +37,10 @@ import org.waveprotocol.wave.model.wave.data.WaveViewData;
 import org.waveprotocol.wave.model.wave.data.impl.WaveViewDataImpl;
 import org.waveprotocol.wave.util.logging.Log;
 
-import java.util.Collection;
 import java.util.Collections;
 import java.util.LinkedHashMap;
 import java.util.List;
+import java.util.Set;
 
 /**
  * Base implementation of search provider.
@@ -72,15 +72,17 @@ public abstract class AbstractSearchProviderImpl implements 
SearchProvider {
     }
   }
 
+  // TODO (yurize) : Refactor this method. It does two things: filtering and
+  // building waves.
   protected LinkedHashMap<WaveId, WaveViewData> 
filterWavesViewBySearchCriteria(
       Function<ReadableWaveletData, Boolean> matchesFunction,
-      Multimap<WaveId, WaveletId> currentUserWavesView) {
+      LinkedHashMultimap<WaveId, WaveletId> currentUserWavesView) {
     // Must use a map with stable ordering, since indices are meaningful.
     LinkedHashMap<WaveId, WaveViewData> results = Maps.newLinkedHashMap();
 
     // Loop over the user waves view.
     for (WaveId waveId : currentUserWavesView.keySet()) {
-      Collection<WaveletId> waveletIds = currentUserWavesView.get(waveId);
+      Set<WaveletId> waveletIds = currentUserWavesView.get(waveId);
       WaveViewData view = buildWaveViewData(waveId, waveletIds, 
matchesFunction, waveMap);
       Iterable<? extends ObservableWaveletData> wavelets = view.getWavelets();
       boolean hasConversation = false;
@@ -97,7 +99,7 @@ public abstract class AbstractSearchProviderImpl implements 
SearchProvider {
     return results;
   }
 
-  public static WaveViewData buildWaveViewData(WaveId waveId, 
Collection<WaveletId> waveletIds,
+  public static WaveViewData buildWaveViewData(WaveId waveId, Set<WaveletId> 
waveletIds,
       Function<ReadableWaveletData, Boolean> matchesFunction, WaveMap waveMap) 
{
 
     WaveViewData view = null; // Copy of the wave built up for search hits.

http://git-wip-us.apache.org/repos/asf/incubator-wave/blob/deb18544/src/org/waveprotocol/box/server/waveserver/SimpleSearchProviderImpl.java
----------------------------------------------------------------------
diff --git 
a/src/org/waveprotocol/box/server/waveserver/SimpleSearchProviderImpl.java 
b/src/org/waveprotocol/box/server/waveserver/SimpleSearchProviderImpl.java
index 917a3b8..a1db671 100644
--- a/src/org/waveprotocol/box/server/waveserver/SimpleSearchProviderImpl.java
+++ b/src/org/waveprotocol/box/server/waveserver/SimpleSearchProviderImpl.java
@@ -20,9 +20,8 @@
 package org.waveprotocol.box.server.waveserver;
 
 import com.google.common.base.Function;
-import com.google.common.collect.HashMultimap;
+import com.google.common.collect.LinkedHashMultimap;
 import com.google.common.collect.Lists;
-import com.google.common.collect.Multimap;
 import com.google.inject.Inject;
 import com.google.inject.name.Named;
 import com.google.wave.api.SearchResult;
@@ -94,7 +93,8 @@ public class SimpleSearchProviderImpl extends 
AbstractSearchProviderImpl {
       return digester.generateSearchResult(user, query, null);
     }
 
-    Multimap<WaveId, WaveletId> currentUserWavesView =  
createWavesViewToFilter(user, isAllQuery);
+    LinkedHashMultimap<WaveId, WaveletId> currentUserWavesView =
+        createWavesViewToFilter(user, isAllQuery);
     Function<ReadableWaveletData, Boolean> filterWaveletsFunction =
         createFilterWaveletsFunction(user, isAllQuery, withParticipantIds, 
creatorParticipantIds);
 
@@ -110,10 +110,10 @@ public class SimpleSearchProviderImpl extends 
AbstractSearchProviderImpl {
     return digester.generateSearchResult(user, query, searchResult);
   }
 
-  private Multimap<WaveId, WaveletId> createWavesViewToFilter(final 
ParticipantId user,
+  private LinkedHashMultimap<WaveId, WaveletId> createWavesViewToFilter(final 
ParticipantId user,
       final boolean isAllQuery) {
-    Multimap<WaveId, WaveletId> currentUserWavesView;
-    currentUserWavesView = HashMultimap.create();
+    LinkedHashMultimap<WaveId, WaveletId> currentUserWavesView;
+    currentUserWavesView = LinkedHashMultimap.create();
     
currentUserWavesView.putAll(waveViewProvider.retrievePerUserWaveView(user));
     if (isAllQuery) {
       // If it is the "all" query - we need to include also waves view of the

http://git-wip-us.apache.org/repos/asf/incubator-wave/blob/deb18544/src/org/waveprotocol/box/server/waveserver/SolrSearchProviderImpl.java
----------------------------------------------------------------------
diff --git 
a/src/org/waveprotocol/box/server/waveserver/SolrSearchProviderImpl.java 
b/src/org/waveprotocol/box/server/waveserver/SolrSearchProviderImpl.java
index fb45f3f..6eb91cd 100644
--- a/src/org/waveprotocol/box/server/waveserver/SolrSearchProviderImpl.java
+++ b/src/org/waveprotocol/box/server/waveserver/SolrSearchProviderImpl.java
@@ -22,7 +22,6 @@ package org.waveprotocol.box.server.waveserver;
 import com.google.common.base.Function;
 import com.google.common.collect.LinkedHashMultimap;
 import com.google.common.collect.Lists;
-import com.google.common.collect.Multimap;
 import com.google.gson.JsonArray;
 import com.google.gson.JsonElement;
 import com.google.gson.JsonObject;
@@ -36,6 +35,8 @@ import org.apache.commons.httpclient.URI;
 import org.apache.commons.httpclient.methods.GetMethod;
 import org.apache.http.HttpStatus;
 import org.waveprotocol.box.server.CoreSettings;
+import org.waveprotocol.wave.model.id.IdConstants;
+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,6 +51,7 @@ import java.util.Collection;
 import java.util.Iterator;
 import java.util.LinkedHashMap;
 import java.util.Map;
+import java.util.Set;
 import java.util.regex.Pattern;
 
 /**
@@ -141,7 +143,7 @@ public class SolrSearchProviderImpl extends 
AbstractSearchProviderImpl {
     // added.
     final boolean isAllQuery = isAllQuery(query);
 
-    Multimap<WaveId, WaveletId> currentUserWavesView = 
LinkedHashMultimap.create();
+    LinkedHashMultimap<WaveId, WaveletId> currentUserWavesView = 
LinkedHashMultimap.create();
 
     if (numResults > 0) {
 
@@ -201,6 +203,8 @@ public class SolrSearchProviderImpl extends 
AbstractSearchProviderImpl {
       }
     }
 
+    ensureWavesHaveUserDataWavelet(currentUserWavesView, user);
+
     Function<ReadableWaveletData, Boolean> matchesFunction =
         new Function<ReadableWaveletData, Boolean>() {
 
@@ -232,6 +236,18 @@ public class SolrSearchProviderImpl extends 
AbstractSearchProviderImpl {
     return digester.generateSearchResult(user, query, searchResult);
   }
 
+  private void ensureWavesHaveUserDataWavelet(
+      LinkedHashMultimap<WaveId, WaveletId> currentUserWavesView, 
ParticipantId user) {
+    WaveletId udw =
+        WaveletId.of(user.getDomain(),
+            IdUtil.join(IdConstants.USER_DATA_WAVELET_PREFIX, 
user.getAddress()));
+    Set<WaveId> waveIds = currentUserWavesView.keySet();
+    for (WaveId waveId : waveIds) {
+      Set<WaveletId> waveletIds = currentUserWavesView.get(waveId);
+      waveletIds.add(udw);
+    }
+  }
+
   public static boolean isAllQuery(String query) {
     return !IN_PATTERN.matcher(query).find();
   }

http://git-wip-us.apache.org/repos/asf/incubator-wave/blob/deb18544/src/org/waveprotocol/box/server/waveserver/SolrWaveIndexerImpl.java
----------------------------------------------------------------------
diff --git 
a/src/org/waveprotocol/box/server/waveserver/SolrWaveIndexerImpl.java 
b/src/org/waveprotocol/box/server/waveserver/SolrWaveIndexerImpl.java
index 8c471ef..3a2fcd0 100644
--- a/src/org/waveprotocol/box/server/waveserver/SolrWaveIndexerImpl.java
+++ b/src/org/waveprotocol/box/server/waveserver/SolrWaveIndexerImpl.java
@@ -76,7 +76,7 @@ import java.util.logging.Level;
  */
 @Singleton
 public class SolrWaveIndexerImpl extends AbstractWaveIndexer implements 
WaveBus.Subscriber,
-    PerUserWaveViewBus.Listener {
+PerUserWaveViewBus.Listener {
 
   private static final Log LOG = Log.get(SolrWaveIndexerImpl.class);
 
@@ -232,8 +232,7 @@ public class SolrWaveIndexerImpl extends 
AbstractWaveIndexer implements WaveBus.
   private void updateIndex(ReadableWaveletData wavelet) throws IndexException {
 
     Preconditions.checkNotNull(wavelet);
-    boolean isUserDataWavelet = 
IdUtil.isUserDataWavelet(wavelet.getWaveletId());
-    if (!(IdUtil.isConversationRootWaveletId(wavelet.getWaveletId()) || 
isUserDataWavelet)) {
+    if (!IdUtil.isConversationalId(wavelet.getWaveletId())) {
       return;
     }
 
@@ -250,7 +249,7 @@ public class SolrWaveIndexerImpl extends 
AbstractWaveIndexer implements WaveBus.
       for (String docName : wavelet.getDocumentIds()) {
         ReadableBlipData document = wavelet.getDocument(docName);
 
-        if (!(IdUtil.isBlipId(docName) || isUserDataWavelet)) {
+        if (!IdUtil.isBlipId(docName)) {
           continue;
         }
 
@@ -425,9 +424,9 @@ public class SolrWaveIndexerImpl extends 
AbstractWaveIndexer implements WaveBus.
     GetMethod getMethod = new GetMethod();
     try {
       getMethod
-          .setURI(new URI(SolrSearchProviderImpl.SOLR_BASE_URL + 
"/update?wt=json"
-              + "&stream.body=<delete><query>" + SolrSearchProviderImpl.Q + 
"</query></delete>",
-              false));
+      .setURI(new URI(SolrSearchProviderImpl.SOLR_BASE_URL + "/update?wt=json"
+          + "&stream.body=<delete><query>" + SolrSearchProviderImpl.Q + 
"</query></delete>",
+          false));
 
       HttpClient httpClient = new HttpClient();
       int statusCode = httpClient.executeMethod(getMethod);

http://git-wip-us.apache.org/repos/asf/incubator-wave/blob/deb18544/src/org/waveprotocol/wave/model/id/IdUtil.java
----------------------------------------------------------------------
diff --git a/src/org/waveprotocol/wave/model/id/IdUtil.java 
b/src/org/waveprotocol/wave/model/id/IdUtil.java
index 6868c80..6549995 100644
--- a/src/org/waveprotocol/wave/model/id/IdUtil.java
+++ b/src/org/waveprotocol/wave/model/id/IdUtil.java
@@ -19,6 +19,8 @@
 
 package org.waveprotocol.wave.model.id;
 
+import org.waveprotocol.wave.model.wave.ParticipantId;
+
 
 /**
  * This class holds useful utilities for ids.
@@ -124,6 +126,16 @@ public class IdUtil implements IdConstants {
   }
 
   /**
+   * Builds user data wavelet id.
+   */
+  public static WaveletId buildUserDataWaveletId(ParticipantId participant) {
+    WaveletId udwId =
+        WaveletId.of(participant.getDomain(),
+            IdUtil.join(IdConstants.USER_DATA_WAVELET_PREFIX, 
participant.getAddress()));
+    return udwId;
+  }
+
+  /**
    * Gets the address that a user data wavelet ID is for.
    *
    * @return UDW address, or {@code null} if the ID is not a user data wavelet
@@ -131,7 +143,7 @@ public class IdUtil implements IdConstants {
    */
   public static final String getUserDataWaveletAddress(WaveletId waveletId) {
     String[] parts = split(waveletId.getId());
-    if (parts.length != 2 || !parts[0].equals(USER_DATA_WAVELET_PREFIX)) {
+    if ((parts.length != 2) || !parts[0].equals(USER_DATA_WAVELET_PREFIX)) {
       return null;
     }
     return parts[1];

Reply via email to