[kune-commits] r1638 - in trunk: . src/main/java/cc/kune/core/client/errors src/main/java/cc/kune/core/client/sitebar/search src/main/java/cc/kune/core/client/state src/main/java/cc/kune/gspace/client/viewers src/main/java/cc/kune/wave/client src/main/java/cc/kune/wave/server src/main/resources src/test/java/cc/kune/core/server src/test/java/cc/kune/core/server/integration src/test/java/cc/kune/wave/server

Vicente J. Ruiz Jurado vjrj_ at ourproject.org
Mon Dec 12 22:47:20 CET 2011


Author: vjrj_
Date: 2011-12-12 22:47:20 +0100 (Mon, 12 Dec 2011)
New Revision: 1638

Added:
   trunk/src/main/java/cc/kune/wave/client/KuneParticipantController.java
Modified:
   trunk/.classpath
   trunk/pom.xml
   trunk/src/main/java/cc/kune/core/client/errors/ErrorHandler.java
   trunk/src/main/java/cc/kune/core/client/sitebar/search/EntitySearchPanel.java
   trunk/src/main/java/cc/kune/core/client/sitebar/search/MultivalueSuggestBox.java
   trunk/src/main/java/cc/kune/core/client/sitebar/search/SearchBoxFactory.java
   trunk/src/main/java/cc/kune/core/client/sitebar/search/SitebarSearchPanel.java
   trunk/src/main/java/cc/kune/core/client/state/StateManagerDefault.java
   trunk/src/main/java/cc/kune/gspace/client/viewers/ContentViewerPanel.java
   trunk/src/main/java/cc/kune/wave/client/KuneStagesProvider.java
   trunk/src/main/java/cc/kune/wave/client/WebClient.java
   trunk/src/main/java/cc/kune/wave/server/WaveMain.java
   trunk/src/main/resources/wave-server.properties
   trunk/src/test/java/cc/kune/core/server/TestHelper.java
   trunk/src/test/java/cc/kune/core/server/integration/IntegrationTestHelper.java
   trunk/src/test/java/cc/kune/wave/server/KuneWaveServiceDefaultTest.java
Log:
Wave code updated (several bug fixed). Wave participants patched (now the creator cannot be deleted). Better Wave-Kune integration.

Modified: trunk/.classpath
===================================================================
--- trunk/.classpath	2011-12-07 12:18:53 UTC (rev 1637)
+++ trunk/.classpath	2011-12-12 21:47:20 UTC (rev 1638)
@@ -13,19 +13,19 @@
   <classpathentry kind="var" path="M2_REPO/aopalliance/aopalliance/1.0/aopalliance-1.0.jar" sourcepath="M2_REPO/aopalliance/aopalliance/1.0/aopalliance-1.0-sources.jar"/>
   <classpathentry kind="var" path="M2_REPO/avalon-framework/avalon-framework/4.1.3/avalon-framework-4.1.3.jar"/>
   <classpathentry kind="var" path="M2_REPO/backport-util-concurrent/backport-util-concurrent/3.1/backport-util-concurrent-3.1.jar" sourcepath="M2_REPO/backport-util-concurrent/backport-util-concurrent/3.1/backport-util-concurrent-3.1-sources.jar"/>
-  <classpathentry kind="var" path="M2_REPO/org/waveprotocol/box/0.3.7/box-0.3.7.jar"/>
-  <classpathentry kind="var" path="M2_REPO/org/waveprotocol/box-src/0.3.7/box-src-0.3.7.jar" sourcepath="M2_REPO/org/waveprotocol/box-src/0.3.7/box-src-0.3.7-sources.jar"/>
+  <classpathentry kind="var" path="M2_REPO/org/waveprotocol/box/0.3.8/box-0.3.8.jar"/>
+  <classpathentry kind="var" path="M2_REPO/org/waveprotocol/box-src/0.3.8/box-src-0.3.8.jar" sourcepath="M2_REPO/org/waveprotocol/box-src/0.3.8/box-src-0.3.8-sources.jar"/>
   <classpathentry kind="var" path="M2_REPO/org/beanshell/bsh/2.0b4/bsh-2.0b4.jar"/>
   <classpathentry kind="var" path="M2_REPO/c3p0/c3p0/0.9.1/c3p0-0.9.1.jar" sourcepath="M2_REPO/c3p0/c3p0/0.9.1/c3p0-0.9.1-sources.jar"/>
   <classpathentry kind="var" path="M2_REPO/cglib/cglib-nodep/2.1_3/cglib-nodep-2.1_3.jar" sourcepath="M2_REPO/cglib/cglib-nodep/2.1_3/cglib-nodep-2.1_3-sources.jar"/>
   <classpathentry kind="var" path="M2_REPO/classworlds/classworlds/1.1-alpha-2/classworlds-1.1-alpha-2.jar"/>
-  <classpathentry kind="var" path="M2_REPO/org/waveprotocol/client/0.3.7/client-0.3.7.jar"/>
-  <classpathentry kind="var" path="M2_REPO/org/waveprotocol/client-common/0.3.7/client-common-0.3.7.jar"/>
-  <classpathentry kind="var" path="M2_REPO/org/waveprotocol/client-common-src/0.3.7/client-common-src-0.3.7.jar" sourcepath="M2_REPO/org/waveprotocol/client-common-src/0.3.7/client-common-src-0.3.7-sources.jar"/>
-  <classpathentry kind="var" path="M2_REPO/org/waveprotocol/client-scheduler-src/0.3.7/client-scheduler-src-0.3.7.jar" sourcepath="M2_REPO/org/waveprotocol/client-scheduler-src/0.3.7/client-scheduler-src-0.3.7-sources.jar"/>
-  <classpathentry kind="var" path="M2_REPO/org/waveprotocol/client-src/0.3.7/client-src-0.3.7.jar" sourcepath="M2_REPO/org/waveprotocol/client-src/0.3.7/client-src-0.3.7-sources.jar"/>
+  <classpathentry kind="var" path="M2_REPO/org/waveprotocol/client/0.3.8/client-0.3.8.jar"/>
+  <classpathentry kind="var" path="M2_REPO/org/waveprotocol/client-common/0.3.8/client-common-0.3.8.jar"/>
+  <classpathentry kind="var" path="M2_REPO/org/waveprotocol/client-common-src/0.3.8/client-common-src-0.3.8.jar" sourcepath="M2_REPO/org/waveprotocol/client-common-src/0.3.8/client-common-src-0.3.8-sources.jar"/>
+  <classpathentry kind="var" path="M2_REPO/org/waveprotocol/client-scheduler-src/0.3.8/client-scheduler-src-0.3.8.jar" sourcepath="M2_REPO/org/waveprotocol/client-scheduler-src/0.3.8/client-scheduler-src-0.3.8-sources.jar"/>
+  <classpathentry kind="var" path="M2_REPO/org/waveprotocol/client-src/0.3.8/client-src-0.3.8.jar" sourcepath="M2_REPO/org/waveprotocol/client-src/0.3.8/client-src-0.3.8-sources.jar"/>
   <classpathentry kind="var" path="M2_REPO/org/cobogw/gwt/cobogw/1.3.1/cobogw-1.3.1.jar"/>
-  <classpathentry kind="var" path="M2_REPO/org/waveprotocol/common-src/0.3.7/common-src-0.3.7.jar" sourcepath="M2_REPO/org/waveprotocol/common-src/0.3.7/common-src-0.3.7-sources.jar"/>
+  <classpathentry kind="var" path="M2_REPO/org/waveprotocol/common-src/0.3.8/common-src-0.3.8.jar" sourcepath="M2_REPO/org/waveprotocol/common-src/0.3.8/common-src-0.3.8-sources.jar"/>
   <classpathentry kind="var" path="M2_REPO/commons-beanutils/commons-beanutils/1.7.0/commons-beanutils-1.7.0.jar" sourcepath="M2_REPO/commons-beanutils/commons-beanutils/1.7.0/commons-beanutils-1.7.0-sources.jar"/>
   <classpathentry kind="var" path="M2_REPO/commons-cli/commons-cli/1.2/commons-cli-1.2.jar" sourcepath="M2_REPO/commons-cli/commons-cli/1.2/commons-cli-1.2-sources.jar"/>
   <classpathentry kind="var" path="M2_REPO/commons-codec/commons-codec/1.4/commons-codec-1.4.jar" sourcepath="M2_REPO/commons-codec/commons-codec/1.4/commons-codec-1.4-sources.jar"/>
@@ -34,8 +34,8 @@
   <classpathentry kind="var" path="M2_REPO/commons-io/commons-io/1.3.1/commons-io-1.3.1.jar" sourcepath="M2_REPO/commons-io/commons-io/1.3.1/commons-io-1.3.1-sources.jar"/>
   <classpathentry kind="var" path="M2_REPO/commons-lang/commons-lang/2.5/commons-lang-2.5.jar" sourcepath="M2_REPO/commons-lang/commons-lang/2.5/commons-lang-2.5-sources.jar"/>
   <classpathentry kind="var" path="M2_REPO/commons-logging/commons-logging/1.1/commons-logging-1.1.jar" sourcepath="M2_REPO/commons-logging/commons-logging/1.1/commons-logging-1.1-sources.jar"/>
-  <classpathentry kind="var" path="M2_REPO/org/waveprotocol/communication-src/0.3.7/communication-src-0.3.7.jar" sourcepath="M2_REPO/org/waveprotocol/communication-src/0.3.7/communication-src-0.3.7-sources.jar"/>
-  <classpathentry kind="var" path="M2_REPO/org/waveprotocol/concurrencycontrol-src/0.3.7/concurrencycontrol-src-0.3.7.jar" sourcepath="M2_REPO/org/waveprotocol/concurrencycontrol-src/0.3.7/concurrencycontrol-src-0.3.7-sources.jar"/>
+  <classpathentry kind="var" path="M2_REPO/org/waveprotocol/communication-src/0.3.8/communication-src-0.3.8.jar" sourcepath="M2_REPO/org/waveprotocol/communication-src/0.3.8/communication-src-0.3.8-sources.jar"/>
+  <classpathentry kind="var" path="M2_REPO/org/waveprotocol/concurrencycontrol-src/0.3.8/concurrencycontrol-src-0.3.8.jar" sourcepath="M2_REPO/org/waveprotocol/concurrencycontrol-src/0.3.8/concurrencycontrol-src-0.3.8-sources.jar"/>
   <classpathentry kind="var" path="M2_REPO/net/sourceforge/cssparser/cssparser/0.9.5/cssparser-0.9.5.jar" sourcepath="M2_REPO/net/sourceforge/cssparser/cssparser/0.9.5/cssparser-0.9.5-sources.jar"/>
   <classpathentry kind="var" path="M2_REPO/dom4j/dom4j/1.6.1/dom4j-1.6.1.jar" sourcepath="M2_REPO/dom4j/dom4j/1.6.1/dom4j-1.6.1-sources.jar"/>
   <classpathentry kind="var" path="M2_REPO/net/sf/dozer/dozer/4.0/dozer-4.0.jar" sourcepath="M2_REPO/net/sf/dozer/dozer/4.0/dozer-4.0-sources.jar"/>
@@ -57,7 +57,7 @@
   <classpathentry kind="var" path="M2_REPO/com/allen_sauer/gwt/log/gwt-log/gwt-log/3.0.1/gwt-log-3.0.1.jar"/>
   <classpathentry kind="var" path="M2_REPO/com/google/gwt/gwt-servlet/2.1.1/gwt-servlet-2.1.1.jar" sourcepath="M2_REPO/com/google/gwt/gwt-servlet/2.1.1/gwt-servlet-2.1.1-sources.jar"/>
   <classpathentry kind="var" path="M2_REPO/com/google/gwt/gwt-user/2.1.1/gwt-user-2.1.1.jar" sourcepath="M2_REPO/com/google/gwt/gwt-user/2.1.1/gwt-user-2.1.1-sources.jar"/>
-  <classpathentry kind="var" path="M2_REPO/org/waveprotocol/gwt-util-src/0.3.7/gwt-util-src-0.3.7.jar" sourcepath="M2_REPO/org/waveprotocol/gwt-util-src/0.3.7/gwt-util-src-0.3.7-sources.jar"/>
+  <classpathentry kind="var" path="M2_REPO/org/waveprotocol/gwt-util-src/0.3.8/gwt-util-src-0.3.8.jar" sourcepath="M2_REPO/org/waveprotocol/gwt-util-src/0.3.8/gwt-util-src-0.3.8-sources.jar"/>
   <classpathentry kind="var" path="M2_REPO/com/allen_sauer/gwt/voices/gwt-voices/gwt-voices/2.0.0/gwt-voices-2.0.0.jar"/>
   <classpathentry kind="var" path="M2_REPO/com/gwtplatform/gwtp-all/0.5/gwtp-all-0.5.jar" sourcepath="M2_REPO/com/gwtplatform/gwtp-all/0.5/gwtp-all-0.5-sources.jar"/>
   <classpathentry kind="var" path="M2_REPO/com/gwtplatform/gwtp-clients-common/0.5/gwtp-clients-common-0.5.jar" sourcepath="M2_REPO/com/gwtplatform/gwtp-clients-common/0.5/gwtp-clients-common-0.5-sources.jar"/>
@@ -114,16 +114,16 @@
   <classpathentry kind="var" path="M2_REPO/org/apache/maven/maven-profile/2.0/maven-profile-2.0.jar" sourcepath="M2_REPO/org/apache/maven/maven-profile/2.0/maven-profile-2.0-sources.jar"/>
   <classpathentry kind="var" path="M2_REPO/org/apache/maven/maven-project/2.0/maven-project-2.0.jar" sourcepath="M2_REPO/org/apache/maven/maven-project/2.0/maven-project-2.0-sources.jar"/>
   <classpathentry kind="var" path="M2_REPO/org/apache/maven/maven-repository-metadata/2.0/maven-repository-metadata-2.0.jar" sourcepath="M2_REPO/org/apache/maven/maven-repository-metadata/2.0/maven-repository-metadata-2.0-sources.jar"/>
-  <classpathentry kind="var" path="M2_REPO/org/waveprotocol/media-src/0.3.7/media-src-0.3.7.jar" sourcepath="M2_REPO/org/waveprotocol/media-src/0.3.7/media-src-0.3.7-sources.jar"/>
+  <classpathentry kind="var" path="M2_REPO/org/waveprotocol/media-src/0.3.8/media-src-0.3.8.jar" sourcepath="M2_REPO/org/waveprotocol/media-src/0.3.8/media-src-0.3.8-sources.jar"/>
   <classpathentry kind="var" path="M2_REPO/org/mockito/mockito-core/1.8.5/mockito-core-1.8.5.jar" sourcepath="M2_REPO/org/mockito/mockito-core/1.8.5/mockito-core-1.8.5-sources.jar"/>
-  <classpathentry kind="var" path="M2_REPO/org/waveprotocol/model-src/0.3.7/model-src-0.3.7.jar" sourcepath="M2_REPO/org/waveprotocol/model-src/0.3.7/model-src-0.3.7-sources.jar"/>
+  <classpathentry kind="var" path="M2_REPO/org/waveprotocol/model-src/0.3.8/model-src-0.3.8.jar" sourcepath="M2_REPO/org/waveprotocol/model-src/0.3.8/model-src-0.3.8-sources.jar"/>
   <classpathentry kind="var" path="M2_REPO/org/mvel/mvel2/2.0.16/mvel2-2.0.16.jar" sourcepath="M2_REPO/org/mvel/mvel2/2.0.16/mvel2-2.0.16-sources.jar"/>
   <classpathentry kind="var" path="M2_REPO/mysql/mysql-connector-java/5.1.13/mysql-connector-java-5.1.13.jar"/>
   <classpathentry kind="var" path="M2_REPO/net/sourceforge/nekohtml/nekohtml/1.9.15/nekohtml-1.9.15.jar" sourcepath="M2_REPO/net/sourceforge/nekohtml/nekohtml/1.9.15/nekohtml-1.9.15-sources.jar"/>
   <classpathentry kind="var" path="M2_REPO/org/objenesis/objenesis/1.0/objenesis-1.0.jar" sourcepath="M2_REPO/org/objenesis/objenesis/1.0/objenesis-1.0-sources.jar"/>
   <classpathentry kind="var" path="M2_REPO/org/codehaus/plexus/plexus-container-default/1.0-alpha-8/plexus-container-default-1.0-alpha-8.jar" sourcepath="M2_REPO/org/codehaus/plexus/plexus-container-default/1.0-alpha-8/plexus-container-default-1.0-alpha-8-sources.jar"/>
   <classpathentry kind="var" path="M2_REPO/org/codehaus/plexus/plexus-utils/1.0.4/plexus-utils-1.0.4.jar" sourcepath="M2_REPO/org/codehaus/plexus/plexus-utils/1.0.4/plexus-utils-1.0.4-sources.jar"/>
-  <classpathentry kind="var" path="M2_REPO/org/waveprotocol/proto-msg/0.3.7/proto-msg-0.3.7.jar"/>
+  <classpathentry kind="var" path="M2_REPO/org/waveprotocol/proto-msg/0.3.8/proto-msg-0.3.8.jar"/>
   <classpathentry kind="var" path="M2_REPO/org/w3c/css/sac/1.3/sac-1.3.jar" sourcepath="M2_REPO/org/w3c/css/sac/1.3/sac-1.3-sources.jar"/>
   <classpathentry kind="var" path="M2_REPO/org/seleniumhq/selenium/selenium-android-driver/2.12.0/selenium-android-driver-2.12.0.jar" sourcepath="M2_REPO/org/seleniumhq/selenium/selenium-android-driver/2.12.0/selenium-android-driver-2.12.0-sources.jar"/>
   <classpathentry kind="var" path="M2_REPO/org/seleniumhq/selenium/selenium-api/2.12.0/selenium-api-2.12.0.jar" sourcepath="M2_REPO/org/seleniumhq/selenium/selenium-api/2.12.0/selenium-api-2.12.0-sources.jar"/>
@@ -147,9 +147,9 @@
   <classpathentry kind="var" path="M2_REPO/stax/stax-api/1.0.1/stax-api-1.0.1.jar"/>
   <classpathentry kind="var" path="M2_REPO/org/testng/testng/6.2.1/testng-6.2.1.jar" sourcepath="M2_REPO/org/testng/testng/6.2.1/testng-6.2.1-sources.jar"/>
   <classpathentry kind="var" path="M2_REPO/tigase/tigase-xmltools/3.3.5/tigase-xmltools-3.3.5.jar" sourcepath="M2_REPO/tigase/tigase-xmltools/3.3.5/tigase-xmltools-3.3.5-sources.jar"/>
-  <classpathentry kind="var" path="M2_REPO/org/waveprotocol/util-src/0.3.7/util-src-0.3.7.jar" sourcepath="M2_REPO/org/waveprotocol/util-src/0.3.7/util-src-0.3.7-sources.jar"/>
+  <classpathentry kind="var" path="M2_REPO/org/waveprotocol/util-src/0.3.8/util-src-0.3.8.jar" sourcepath="M2_REPO/org/waveprotocol/util-src/0.3.8/util-src-0.3.8-sources.jar"/>
   <classpathentry kind="var" path="M2_REPO/org/apache/maven/wagon/wagon-provider-api/1.0-alpha-5/wagon-provider-api-1.0-alpha-5.jar" sourcepath="M2_REPO/org/apache/maven/wagon/wagon-provider-api/1.0-alpha-5/wagon-provider-api-1.0-alpha-5-sources.jar"/>
-  <classpathentry kind="var" path="M2_REPO/org/waveprotocol/waveinabox-server-0.3/0.3.7/waveinabox-server-0.3-0.3.7.jar"/>
+  <classpathentry kind="var" path="M2_REPO/org/waveprotocol/waveinabox-server-0.3/0.3.8/waveinabox-server-0.3-0.3.8.jar"/>
   <classpathentry kind="var" path="M2_REPO/xalan/xalan/2.7.1/xalan-2.7.1.jar" sourcepath="M2_REPO/xalan/xalan/2.7.1/xalan-2.7.1-sources.jar"/>
   <classpathentry kind="var" path="M2_REPO/xerces/xercesImpl/2.9.1/xercesImpl-2.9.1.jar"/>
   <classpathentry kind="var" path="M2_REPO/xml-apis/xml-apis/1.0.b2/xml-apis-1.0.b2.jar" sourcepath="M2_REPO/xml-apis/xml-apis/1.0.b2/xml-apis-1.0.b2-sources.jar"/>

Modified: trunk/pom.xml
===================================================================
--- trunk/pom.xml	2011-12-07 12:18:53 UTC (rev 1637)
+++ trunk/pom.xml	2011-12-12 21:47:20 UTC (rev 1638)
@@ -19,7 +19,7 @@
     <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
     <slf4j.version>1.6.1</slf4j.version>
     <openjpa.version>2.0.1</openjpa.version>
-    <wiab.version>0.3.7</wiab.version>
+    <wiab.version>0.3.8</wiab.version>
     <skipTests>true</skipTests>
   </properties>
   <repositories>

Modified: trunk/src/main/java/cc/kune/core/client/errors/ErrorHandler.java
===================================================================
--- trunk/src/main/java/cc/kune/core/client/errors/ErrorHandler.java	2011-12-07 12:18:53 UTC (rev 1637)
+++ trunk/src/main/java/cc/kune/core/client/errors/ErrorHandler.java	2011-12-12 21:47:20 UTC (rev 1638)
@@ -84,7 +84,7 @@
       final String msg = caught.getMessage();
       eventBus.fireEvent(new UserNotifyEvent(NotifyLevel.error,
           i18n.t("You do not have rights to perform that action")
-              + (!TextUtils.empty(msg) && msg.length() > 1 ? ". " + i18n.t(msg) : "")));
+              + (!TextUtils.empty(msg) && msg.length() > 2 ? ". " + i18n.t(msg) : "")));
       goHome();
     } else if (caught instanceof SessionExpiredException) {
       logException(caught);

Modified: trunk/src/main/java/cc/kune/core/client/sitebar/search/EntitySearchPanel.java
===================================================================
--- trunk/src/main/java/cc/kune/core/client/sitebar/search/EntitySearchPanel.java	2011-12-07 12:18:53 UTC (rev 1637)
+++ trunk/src/main/java/cc/kune/core/client/sitebar/search/EntitySearchPanel.java	2011-12-12 21:47:20 UTC (rev 1638)
@@ -71,7 +71,7 @@
     dialog.getTitleText().setText(
         i18n.t(searchOnlyUsers ? "Type the name of the user and select him/her:"
             : "Type the name of the user or group and select it:"), i18n.getDirection());
-    final MultivalueSuggestBox multivalueSBox = SearchBoxFactory.create(i18n, searchOnlyUsers, id,
+    final MultivalueSuggestBox multivalueSBox = SearchBoxFactory.create(i18n, searchOnlyUsers, true, id,
         callback);
     suggestBox = multivalueSBox.getSuggestBox();
     searchTextBox = suggestBox.getTextBox();

Modified: trunk/src/main/java/cc/kune/core/client/sitebar/search/MultivalueSuggestBox.java
===================================================================
--- trunk/src/main/java/cc/kune/core/client/sitebar/search/MultivalueSuggestBox.java	2011-12-07 12:18:53 UTC (rev 1637)
+++ trunk/src/main/java/cc/kune/core/client/sitebar/search/MultivalueSuggestBox.java	2011-12-12 21:47:20 UTC (rev 1638)
@@ -311,9 +311,11 @@
       if (totSize < 1) {
         // if there were no suggestions, then it's an invalid value
         updateFormFeedback(FormFeedback.ERROR, "Invalid: " + m_query);
-        final OptionSuggestion sugg = new OptionSuggestion(i18n.t("No results"), "#",
-            m_request.getQuery(), m_query);
-        suggs.add(sugg);
+        if (showNoResult) {
+          final OptionSuggestion sugg = new OptionSuggestion(i18n.t("No results"), "#",
+              m_request.getQuery(), m_query);
+          suggs.add(sugg);
+        }
       } else if (false && totSize == 1) {
         // Patch to show always the suggestions
         // it's an exact match, so do not bother with showing suggestions,
@@ -497,6 +499,8 @@
 
   private final Map<String, String> mvalueMap;
 
+  private final boolean showNoResult;
+
   // private final OnExactMatch onExactMatch;
 
   /**
@@ -510,10 +514,14 @@
    * @param isMultivalued
    *          - true for allowing multiple values
    * @param onExactMatch
+   * @param showNoResult
+   *          if we have to show noResult message when the search is empty or
+   *          not
    */
-  public MultivalueSuggestBox(final I18nUITranslationService i18n, final String restEndpointUrl,
-      final boolean isMultivalued, final OnExactMatch onExactMatch) {
+  public MultivalueSuggestBox(final I18nUITranslationService i18n, final boolean showNoResult,
+      final String restEndpointUrl, final boolean isMultivalued, final OnExactMatch onExactMatch) {
     this.i18n = i18n;
+    this.showNoResult = showNoResult;
     mrestEndpointUrl = restEndpointUrl;
     misMultivalued = isMultivalued;
     // this.onExactMatch = onExactMatch;

Modified: trunk/src/main/java/cc/kune/core/client/sitebar/search/SearchBoxFactory.java
===================================================================
--- trunk/src/main/java/cc/kune/core/client/sitebar/search/SearchBoxFactory.java	2011-12-07 12:18:53 UTC (rev 1637)
+++ trunk/src/main/java/cc/kune/core/client/sitebar/search/SearchBoxFactory.java	2011-12-12 21:47:20 UTC (rev 1638)
@@ -31,9 +31,11 @@
 public class SearchBoxFactory {
 
   public static MultivalueSuggestBox create(final I18nUITranslationService i18n,
-      final boolean searchOnlyUsers, final String id, final OnEntitySelectedInSearch callback) {
+      final boolean searchOnlyUsers, final boolean showNoResult, final String id,
+      final OnEntitySelectedInSearch callback) {
     final MultivalueSuggestBox multivalueSBox = new MultivalueSuggestBox(
         i18n,
+        showNoResult,
         searchOnlyUsers ? SearcherConstants.USER_DATA_PROXY_URL : SearcherConstants.GROUP_DATA_PROXY_URL,
         false, new OnExactMatch() {
 

Modified: trunk/src/main/java/cc/kune/core/client/sitebar/search/SitebarSearchPanel.java
===================================================================
--- trunk/src/main/java/cc/kune/core/client/sitebar/search/SitebarSearchPanel.java	2011-12-07 12:18:53 UTC (rev 1637)
+++ trunk/src/main/java/cc/kune/core/client/sitebar/search/SitebarSearchPanel.java	2011-12-12 21:47:20 UTC (rev 1638)
@@ -53,7 +53,7 @@
       final StateManager stateManager, final I18nUITranslationService i18n) {
     searchButton = new PushButton(new Image(img.kuneSearchIco()), new Image(img.kuneSearchIcoPush()));
     searchButton.ensureDebugId(SITE_SEARCH_BUTTON);
-    final MultivalueSuggestBox multivalueSBox = SearchBoxFactory.create(i18n, false,
+    final MultivalueSuggestBox multivalueSBox = SearchBoxFactory.create(i18n, false, true,
         SITE_SEARCH_TEXTBOX, new OnEntitySelectedInSearch() {
           @Override
           public void onSeleted(final String shortName) {

Modified: trunk/src/main/java/cc/kune/core/client/state/StateManagerDefault.java
===================================================================
--- trunk/src/main/java/cc/kune/core/client/state/StateManagerDefault.java	2011-12-07 12:18:53 UTC (rev 1637)
+++ trunk/src/main/java/cc/kune/core/client/state/StateManagerDefault.java	2011-12-12 21:47:20 UTC (rev 1638)
@@ -21,8 +21,8 @@
 package cc.kune.core.client.state;
 
 import org.waveprotocol.box.webclient.client.ClientEvents;
-import org.waveprotocol.box.webclient.client.HistorySupport;
 import org.waveprotocol.box.webclient.client.events.WaveSelectionEvent;
+import org.waveprotocol.wave.model.waveref.InvalidWaveRefException;
 import org.waveprotocol.wave.util.escapers.GwtWaverefEncoder;
 
 import cc.kune.common.client.actions.BeforeActionCollection;
@@ -290,8 +290,12 @@
           if (session.isLogged()) {
             SpaceConfEvent.fire(eventBus, Space.userSpace, newHistoryToken);
             SpaceSelectEvent.fire(eventBus, Space.userSpace);
-            ClientEvents.get().fireEvent(
-                new WaveSelectionEvent(HistorySupport.waveRefFromHistoryToken(newHistoryToken)));
+            try {
+              ClientEvents.get().fireEvent(
+                  new WaveSelectionEvent(GwtWaverefEncoder.decodeWaveRefFromPath(newHistoryToken)));
+            } catch (final InvalidWaveRefException e) {
+              Log.error(nToken, e);
+            }
           } else {
             // Wave, but don't logged
             history.newItem(TokenUtils.addRedirect(SiteTokens.SIGNIN, newHistoryToken));

Modified: trunk/src/main/java/cc/kune/gspace/client/viewers/ContentViewerPanel.java
===================================================================
--- trunk/src/main/java/cc/kune/gspace/client/viewers/ContentViewerPanel.java	2011-12-07 12:18:53 UTC (rev 1637)
+++ trunk/src/main/java/cc/kune/gspace/client/viewers/ContentViewerPanel.java	2011-12-12 21:47:20 UTC (rev 1638)
@@ -78,6 +78,7 @@
   @UiField
   DeckPanel deck;
   private final GSpaceArmor gsArmor;
+  private final I18nTranslationService i18n;
   private IdGenerator idGenerator;
   private Element loading;
   @UiField
@@ -85,6 +86,7 @@
   private ProfileManager profiles;
   /** The wave panel, if a wave is open. */
   private KuneStagesProvider wave;
+
   private final WaveClientProvider waveClientProv;
 
   private ImplPanel waveHolder;
@@ -103,6 +105,7 @@
     this.gsArmor = wsArmor;
     this.waveClientProv = waveClient;
     this.capabilitiesRegistry = capabilitiesRegistry;
+    this.i18n = i18n;
     widget = uiBinder.createAndBindUi(this);
     contentTitle = new ContentTitleWidget(i18n, gsArmor, capabilitiesRegistry.getIconsRegistry());
     eventBus.addHandler(WaveClientClearEvent.getType(),
@@ -219,7 +222,7 @@
       final Element holder = waveHolder.getElement().appendChild(Document.get().createDivElement());
       final KuneStagesProvider wave = new KuneStagesProvider(holder, waveHolder, waveRef, channel,
           idGenerator, profiles, waveStore, isNewWave,
-          org.waveprotocol.box.webclient.client.Session.get().getDomain(), true);
+          org.waveprotocol.box.webclient.client.Session.get().getDomain(), true, i18n);
       this.wave = wave;
       wave.load(new Command() {
         @Override

Added: trunk/src/main/java/cc/kune/wave/client/KuneParticipantController.java
===================================================================
--- trunk/src/main/java/cc/kune/wave/client/KuneParticipantController.java	                        (rev 0)
+++ trunk/src/main/java/cc/kune/wave/client/KuneParticipantController.java	2011-12-12 21:47:20 UTC (rev 1638)
@@ -0,0 +1,156 @@
+/**
+ * Copyright 2010 Google Inc.
+ *
+ * Licensed 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 cc.kune.wave.client;
+
+import org.waveprotocol.wave.client.account.Profile;
+import org.waveprotocol.wave.client.account.ProfileManager;
+import org.waveprotocol.wave.client.common.safehtml.EscapeUtils;
+import org.waveprotocol.wave.client.wavepanel.WavePanel;
+import org.waveprotocol.wave.client.wavepanel.event.EventHandlerRegistry;
+import org.waveprotocol.wave.client.wavepanel.event.WaveClickHandler;
+import org.waveprotocol.wave.client.wavepanel.view.ParticipantView;
+import org.waveprotocol.wave.client.wavepanel.view.ParticipantsView;
+import org.waveprotocol.wave.client.wavepanel.view.View.Type;
+import org.waveprotocol.wave.client.wavepanel.view.dom.DomAsViewProvider;
+import org.waveprotocol.wave.client.wavepanel.view.dom.ModelAsViewProvider;
+import org.waveprotocol.wave.client.wavepanel.view.dom.full.TypeCodes;
+import org.waveprotocol.wave.client.widget.profile.ProfilePopupPresenter;
+import org.waveprotocol.wave.client.widget.profile.ProfilePopupView;
+import org.waveprotocol.wave.model.conversation.Conversation;
+import org.waveprotocol.wave.model.util.Pair;
+import org.waveprotocol.wave.model.wave.InvalidParticipantAddress;
+import org.waveprotocol.wave.model.wave.ParticipantId;
+
+import cc.kune.common.client.notify.NotifyUser;
+import cc.kune.core.shared.i18n.I18nTranslationService;
+
+import com.google.gwt.dom.client.Element;
+import com.google.gwt.event.dom.client.ClickEvent;
+import com.google.gwt.event.dom.client.ClickHandler;
+import com.google.gwt.user.client.Window;
+
+/**
+ * Installs the add/remove participant controls.
+ * 
+ */
+public final class KuneParticipantController {
+  private static I18nTranslationService i18n;
+
+  /**
+   * Builds and installs the participant control feature.
+   */
+  public static void install(final WavePanel panel, final ModelAsViewProvider models,
+      final ProfileManager profiles, final String localDomain, final I18nTranslationService i18n) {
+    KuneParticipantController.i18n = i18n;
+    final KuneParticipantController controller = new KuneParticipantController(panel.getViewProvider(),
+        models, profiles, localDomain);
+    controller.install(panel.getHandlers());
+  }
+  private final String localDomain;
+  private final ModelAsViewProvider models;
+  private final ProfileManager profiles;
+
+  private final DomAsViewProvider views;
+
+  /**
+   * @param localDomain
+   *          nullable. if provided, automatic suffixing will occur.
+   */
+  KuneParticipantController(final DomAsViewProvider views, final ModelAsViewProvider models,
+      final ProfileManager profiles, final String localDomain) {
+    this.views = views;
+    this.models = models;
+    this.profiles = profiles;
+    this.localDomain = localDomain;
+  }
+
+  /**
+   * Shows an add-participant popup.
+   */
+  private void handleAddButtonClicked(final Element context) {
+
+    ParticipantId p;
+    String address = Window.prompt("Add a participant: ", "");
+    if (address == null) {
+      return;
+    }
+    address = address.trim();
+    if (localDomain != null) {
+      if (!address.isEmpty() && address.indexOf("@") == -1) {
+        // If no domain was specified, assume that the participant is from the
+        // local domain.
+        address = address + "@" + localDomain;
+      } else if (address.equals("@")) {
+        // "@" is a shortcut for the shared domain participant.
+        address = address + localDomain;
+      }
+    }
+
+    try {
+      p = ParticipantId.of(address);
+    } catch (final InvalidParticipantAddress e) {
+      NotifyUser.error(i18n.t("Invalid address: [%s]", address));
+      return;
+    }
+
+    final ParticipantsView participantsUi = views.fromAddButton(context);
+    final Conversation conversation = models.getParticipants(participantsUi);
+    conversation.addParticipant(p);
+  }
+
+  /**
+   * Shows a participation popup for the clicked participant.
+   */
+  private void handleParticipantClicked(final Element context) {
+    final ParticipantView participantView = views.asParticipant(context);
+    final Pair<Conversation, ParticipantId> participation = models.getParticipant(participantView);
+    final Profile profile = profiles.getProfile(participation.second);
+
+    // Summon a popup view from a participant, and attach profile-popup logic to
+    // it.
+    final ProfilePopupView profileView = participantView.showParticipation();
+    final ProfilePopupPresenter profileUi = ProfilePopupPresenter.create(profile, profileView, profiles);
+    if (!participation.first.getParticipantIds().iterator().next().equals(participation.getSecond())) {
+      profileUi.addControl(EscapeUtils.fromSafeConstant("Remove"), new ClickHandler() {
+        @Override
+        public void onClick(final ClickEvent event) {
+          participation.first.removeParticipant(participation.second);
+          // The presenter is configured to destroy itself on view hide.
+          profileView.hide();
+        }
+      });
+    }
+    profileUi.show();
+  }
+
+  private void install(final EventHandlerRegistry handlers) {
+    handlers.registerClickHandler(TypeCodes.kind(Type.ADD_PARTICIPANT), new WaveClickHandler() {
+      @Override
+      public boolean onClick(final ClickEvent event, final Element context) {
+        handleAddButtonClicked(context);
+        return true;
+      }
+    });
+    handlers.registerClickHandler(TypeCodes.kind(Type.PARTICIPANT), new WaveClickHandler() {
+      @Override
+      public boolean onClick(final ClickEvent event, final Element context) {
+        handleParticipantClicked(context);
+        return true;
+      }
+    });
+  }
+}

Modified: trunk/src/main/java/cc/kune/wave/client/KuneStagesProvider.java
===================================================================
--- trunk/src/main/java/cc/kune/wave/client/KuneStagesProvider.java	2011-12-07 12:18:53 UTC (rev 1637)
+++ trunk/src/main/java/cc/kune/wave/client/KuneStagesProvider.java	2011-12-12 21:47:20 UTC (rev 1638)
@@ -32,14 +32,30 @@
 import org.waveprotocol.wave.client.common.util.AsyncHolder;
 import org.waveprotocol.wave.client.common.util.AsyncHolder.Accessor;
 import org.waveprotocol.wave.client.common.util.LogicalPanel;
+import org.waveprotocol.wave.client.editor.EditorStaticDeps;
+import org.waveprotocol.wave.client.wavepanel.impl.WavePanelImpl;
+import org.waveprotocol.wave.client.wavepanel.impl.edit.Actions;
+import org.waveprotocol.wave.client.wavepanel.impl.edit.EditController;
+import org.waveprotocol.wave.client.wavepanel.impl.edit.EditSession;
+import org.waveprotocol.wave.client.wavepanel.impl.edit.KeepFocusInView;
+import org.waveprotocol.wave.client.wavepanel.impl.focus.FocusFramePresenter;
+import org.waveprotocol.wave.client.wavepanel.impl.indicator.ReplyIndicatorController;
+import org.waveprotocol.wave.client.wavepanel.impl.menu.MenuController;
+import org.waveprotocol.wave.client.wavepanel.impl.title.WaveTitleHandler;
+import org.waveprotocol.wave.client.wavepanel.impl.toolbar.ToolbarSwitcher;
 import org.waveprotocol.wave.client.wavepanel.view.BlipView;
 import org.waveprotocol.wave.client.wavepanel.view.dom.ModelAsViewProvider;
 import org.waveprotocol.wave.client.wavepanel.view.dom.full.BlipQueueRenderer;
 import org.waveprotocol.wave.client.wavepanel.view.dom.full.DomRenderer;
+import org.waveprotocol.wave.client.widget.popup.PopupChromeFactory;
+import org.waveprotocol.wave.client.widget.popup.PopupFactory;
 import org.waveprotocol.wave.model.conversation.ConversationView;
 import org.waveprotocol.wave.model.id.IdGenerator;
+import org.waveprotocol.wave.model.wave.ParticipantId;
 import org.waveprotocol.wave.model.waveref.WaveRef;
 
+import cc.kune.core.shared.i18n.I18nTranslationService;
+
 import com.google.gwt.dom.client.Element;
 
 /**
@@ -51,28 +67,30 @@
 
   private final static AsyncHolder<Object> HALT = new AsyncHolder<Object>() {
     @Override
-    public void call(Accessor<Object> accessor) {
+    public void call(final Accessor<Object> accessor) {
       // Never ready, so never notify the accessor.
     }
   };
 
-  private final Element wavePanelElement;
-  private final LogicalPanel rootPanel;
-  private final WaveRef waveRef;
   private final RemoteViewServiceMultiplexer channel;
+  private boolean closed;
+  private final I18nTranslationService i18n;
   private final IdGenerator idGenerator;
-  private final ProfileManager profiles;
-  private final WaveStore waveStore;
   private final boolean isNewWave;
   private final String localDomain;
+  private StageOne one;
+  private final ProfileManager profiles;
+  private final LogicalPanel rootPanel;
 
-  private boolean closed;
-  private StageOne one;
+  private final boolean showParticipantsPanel;
+  private StageThree three;
   private StageTwo two;
-  private StageThree three;
   private WaveContext wave;
-  private boolean showParticipantsPanel;
+  private final Element wavePanelElement;
+  private final WaveRef waveRef;
 
+  private final WaveStore waveStore;
+
   /**
    * @param wavePanelElement The dom element to become the wave panel
    * @param rootPanel A panel that this an ancestor of wavePanelElement. This is
@@ -83,9 +101,9 @@
    * @param isNewWave true if the wave is a new client-created wave
    * @param idGenerator
    */
-  public KuneStagesProvider(Element wavePanelElement, LogicalPanel rootPanel, WaveRef waveRef,
-      RemoteViewServiceMultiplexer channel, IdGenerator idGenerator, ProfileManager profiles,
-      WaveStore store, boolean isNewWave, String localDomain, boolean showParticipantsPanel) {
+  public KuneStagesProvider(final Element wavePanelElement, final LogicalPanel rootPanel, final WaveRef waveRef,
+      final RemoteViewServiceMultiplexer channel, final IdGenerator idGenerator, final ProfileManager profiles,
+      final WaveStore store, final boolean isNewWave, final String localDomain, final boolean showParticipantsPanel, final I18nTranslationService i18n) {
     this.wavePanelElement = wavePanelElement;
     this.rootPanel = rootPanel;
     this.waveRef = waveRef;
@@ -96,46 +114,21 @@
     this.isNewWave = isNewWave;
     this.localDomain = localDomain;
     this.showParticipantsPanel = showParticipantsPanel;
+    this.i18n = i18n;
   }
 
   @Override
-  protected AsyncHolder<StageZero> createStageZeroLoader() {
-    return haltIfClosed(super.createStageZeroLoader());
-  }
-
-  @Override
-  protected AsyncHolder<StageOne> createStageOneLoader(StageZero zero) {
+  protected AsyncHolder<StageOne> createStageOneLoader(final StageZero zero) {
     return haltIfClosed(new StageOne.DefaultProvider(zero) {
       @Override
-      protected Element createWaveHolder() {
-        return wavePanelElement;
-      }
-
-      @Override
       protected LogicalPanel createWaveContainer() {
         return rootPanel;
       }
-    });
-  }
 
-  @Override
-  protected AsyncHolder<StageTwo> createStageTwoLoader(StageOne one) {
-    return haltIfClosed(new StageTwoProvider(
-        this.one = one, waveRef, channel, isNewWave, idGenerator, profiles) {
-      // Kune patch
       @Override
-      protected DomRenderer createRenderer() {
-        return KuneFullDomWaveRendererImpl.create(getConversations(), getProfileManager(),
-            getBlipDetailer(), getViewIdMapper(), getBlipQueue(), getThreadReadStateMonitor(),
-            createViewFactories(), showParticipantsPanel);
+      protected Element createWaveHolder() {
+        return wavePanelElement;
       }
-
-      // Warning: this run into issue #73
-      //      @Override
-      //      protected void installFeatures() {
-      //        WavePanelResourceLoader.loadCss();
-      //        // KuneWavePanelResourceLoader.loadCss();
-      //      }
     });
   }
 
@@ -147,7 +140,7 @@
         // Prepend an init wave flow onto the stage continuation.
         super.create(new Accessor<StageThree>() {
           @Override
-          public void use(StageThree x) {
+          public void use(final StageThree x) {
             onStageThreeLoaded(x, whenReady);
           }
         });
@@ -157,41 +150,57 @@
       protected String getLocalDomain() {
         return localDomain;
       }
+      @Override
+      protected void install() {
+        EditorStaticDeps.setPopupProvider(PopupFactory.getProvider());
+        EditorStaticDeps.setPopupChromeProvider(PopupChromeFactory.getProvider());
+
+        // Eagerly install some features.
+        final WavePanelImpl panel = stageTwo.getStageOne().getWavePanel();
+        final FocusFramePresenter focus = stageTwo.getStageOne().getFocusFrame();
+        final ParticipantId user = stageTwo.getSignedInUser();
+        final ModelAsViewProvider models = stageTwo.getModelAsViewProvider();
+        final ProfileManager profiles = stageTwo.getProfileManager();
+
+        final Actions actions = getEditActions();
+        final EditSession edit = getEditSession();
+        MenuController.install(actions, panel);
+        ToolbarSwitcher.install(stageTwo.getStageOne().getWavePanel(), getEditSession(),
+            getViewToolbar(), getEditToolbar());
+        WaveTitleHandler.install(edit, models);
+        ReplyIndicatorController.install(actions, edit, panel);
+        EditController.install(focus, actions, panel);
+       KuneParticipantController.install(panel, models, profiles, getLocalDomain(), i18n);
+        KeepFocusInView.install(edit, panel);
+        stageTwo.getDiffController().upgrade(edit);
+      }
     });
   }
 
-  private void onStageThreeLoaded(StageThree x, Accessor<StageThree> whenReady) {
-    if (closed) {
-      // Stop the loading process.
-      return;
-    }
-    three = x;
-    if (isNewWave) {
-      initNewWave(x);
-    } else {
-      handleExistingWave(x);
-    }
-    wave = new WaveContext(
-        two.getWave(), two.getConversations(), two.getSupplement(), two.getReadMonitor());
-    waveStore.add(wave);
-    whenReady.use(x);
-  }
+  @Override
+  protected AsyncHolder<StageTwo> createStageTwoLoader(final StageOne one) {
+    return haltIfClosed(new StageTwoProvider(
+        this.one = one, waveRef, channel, isNewWave, idGenerator, profiles) {
+      // Kune patch
+      @Override
+      protected DomRenderer createRenderer() {
+        return KuneFullDomWaveRendererImpl.create(getConversations(), getProfileManager(),
+            getBlipDetailer(), getViewIdMapper(), getBlipQueue(), getThreadReadStateMonitor(),
+            createViewFactories(), showParticipantsPanel);
+      }
 
-  private void initNewWave(StageThree three) {
-    // Do the new-wave flow.
-    ModelAsViewProvider views = two.getModelAsViewProvider();
-    BlipQueueRenderer blipQueue = two.getBlipQueue();
-    ConversationView wave = two.getConversations();
-
-    // Force rendering to finish.
-    blipQueue.flush();
-    BlipView blipUi = views.getBlipView(wave.getRoot().getRootThread().getFirstBlip());
-    three.getEditActions().startEditing(blipUi);
+      // Warning: this run into issue #73
+      //      @Override
+      //      protected void installFeatures() {
+      //        WavePanelResourceLoader.loadCss();
+      //        // KuneWavePanelResourceLoader.loadCss();
+      //      }
+    });
   }
 
-  private void handleExistingWave(StageThree three) {
-      BlipQueueRenderer blipQueue = two.getBlipQueue();
-      blipQueue.flush();
+  @Override
+  protected AsyncHolder<StageZero> createStageZeroLoader() {
+    return haltIfClosed(super.createStageZeroLoader());
   }
 
   public void destroy() {
@@ -219,7 +228,41 @@
    *         given provider.
    */
   @SuppressWarnings("unchecked") // HALT is safe as a holder for any type
-  private <T> AsyncHolder<T> haltIfClosed(AsyncHolder<T> provider) {
+  private <T> AsyncHolder<T> haltIfClosed(final AsyncHolder<T> provider) {
     return closed ? (AsyncHolder<T>) HALT : provider;
   }
+
+  private void handleExistingWave(final StageThree three) {
+      final BlipQueueRenderer blipQueue = two.getBlipQueue();
+      blipQueue.flush();
+  }
+
+  private void initNewWave(final StageThree three) {
+    // Do the new-wave flow.
+    final ModelAsViewProvider views = two.getModelAsViewProvider();
+    final BlipQueueRenderer blipQueue = two.getBlipQueue();
+    final ConversationView wave = two.getConversations();
+
+    // Force rendering to finish.
+    blipQueue.flush();
+    final BlipView blipUi = views.getBlipView(wave.getRoot().getRootThread().getFirstBlip());
+    three.getEditActions().startEditing(blipUi);
+  }
+
+  private void onStageThreeLoaded(final StageThree x, final Accessor<StageThree> whenReady) {
+    if (closed) {
+      // Stop the loading process.
+      return;
+    }
+    three = x;
+    if (isNewWave) {
+      initNewWave(x);
+    } else {
+      handleExistingWave(x);
+    }
+    wave = new WaveContext(
+        two.getWave(), two.getConversations(), two.getSupplement(), two.getReadMonitor());
+    waveStore.add(wave);
+    whenReady.use(x);
+  }
 }

Modified: trunk/src/main/java/cc/kune/wave/client/WebClient.java
===================================================================
--- trunk/src/main/java/cc/kune/wave/client/WebClient.java	2011-12-07 12:18:53 UTC (rev 1637)
+++ trunk/src/main/java/cc/kune/wave/client/WebClient.java	2011-12-12 21:47:20 UTC (rev 1638)
@@ -64,7 +64,9 @@
 import org.waveprotocol.wave.model.id.IdGenerator;
 import org.waveprotocol.wave.model.id.WaveId;
 import org.waveprotocol.wave.model.wave.ParticipantId;
+import org.waveprotocol.wave.model.waveref.InvalidWaveRefException;
 import org.waveprotocol.wave.model.waveref.WaveRef;
+import org.waveprotocol.wave.util.escapers.GwtWaverefEncoder;
 
 import cc.kune.common.client.notify.NotifyUser;
 import cc.kune.core.client.errors.DefaultException;
@@ -72,6 +74,7 @@
 import cc.kune.core.client.sitebar.spaces.SpaceConfEvent;
 import cc.kune.core.client.state.SiteTokens;
 import cc.kune.core.client.state.TokenMatcher;
+import cc.kune.core.shared.i18n.I18nTranslationService;
 import cc.kune.wave.client.inboxcount.InboxCountPresenter;
 
 import com.google.gwt.core.client.GWT;
@@ -225,13 +228,15 @@
 
   private final EventBus eventBus;
 
+  private final I18nTranslationService i18n;
+
   private IdGenerator idGenerator;
 
   private final InboxCountPresenter inboxCount;
 
   private final Element loading = new LoadingIndicator().getElement();
+  private ParticipantId loggedInUser;
 
-  private ParticipantId loggedInUser;
   @UiField
   DebugMessagePanel logPanel;
 
@@ -257,7 +262,6 @@
   ImplPanel waveHolder;
 
   private final WaveStore waveStore = new SimpleWaveStore();
-
   /**
    * Create a remote websocket to talk to the server-side FedOne service.
    */
@@ -267,11 +271,12 @@
    * This is the entry point method.
    */
   @Inject
-  public WebClient(final EventBus eventBus, final KuneWaveProfileManager profiles, final InboxCountPresenter inboxCount, final TokenMatcher tokenMatcher, final cc.kune.core.client.state.Session session) {
+  public WebClient(final EventBus eventBus, final KuneWaveProfileManager profiles, final InboxCountPresenter inboxCount, final TokenMatcher tokenMatcher, final cc.kune.core.client.state.Session session, final I18nTranslationService i18n) {
     // Window.alert("webclient! " + new Date());
     this.eventBus = eventBus;
     this.profiles = profiles;
     this.inboxCount = inboxCount;
+    this.i18n = i18n;
     searchPanel = new SearchPanelWidget(new SearchPanelRenderer(profiles));
     ErrorHandler.install();
 
@@ -427,7 +432,7 @@
     waveHolder.getElement().appendChild(loading);
     final Element holder = waveHolder.getElement().appendChild(Document.get().createDivElement());
     final KuneStagesProvider wave = new KuneStagesProvider(
-        holder, waveHolder, waveRef, channel, idGenerator, profiles, waveStore, isNewWave, Session.get().getDomain(), true);
+        holder, waveHolder, waveRef, channel, idGenerator, profiles, waveStore, isNewWave, Session.get().getDomain(), true, i18n);
     this.wave = wave;
     wave.load(new Command() {
       @Override
@@ -438,8 +443,10 @@
     final String encodedToken = History.getToken();
     // Kune patch
     if (encodedToken != null && !encodedToken.isEmpty() && !encodedToken.equals(SiteTokens.WAVEINBOX)) {
-      final WaveRef fromWaveRef = HistorySupport.waveRefFromHistoryToken(encodedToken);
-      if (waveRef == null) {
+      WaveRef fromWaveRef;
+      try {
+        fromWaveRef = GwtWaverefEncoder.decodeWaveRefFromPath(encodedToken);
+      } catch (final InvalidWaveRefException e) {
         LOG.info("History token contains invalid path: " + encodedToken);
         return;
       }
@@ -450,7 +457,7 @@
         return;
       }
     }
-    final String tokenFromWaveref = HistorySupport.historyTokenFromWaveref(waveRef);
+    final String tokenFromWaveref = GwtWaverefEncoder.encodeToUriPathSegment(waveRef);
     SpaceConfEvent.fire(eventBus, Space.userSpace, tokenFromWaveref);
     History.newItem(tokenFromWaveref, false);
   }

Modified: trunk/src/main/java/cc/kune/wave/server/WaveMain.java
===================================================================
--- trunk/src/main/java/cc/kune/wave/server/WaveMain.java	2011-12-07 12:18:53 UTC (rev 1637)
+++ trunk/src/main/java/cc/kune/wave/server/WaveMain.java	2011-12-12 21:47:20 UTC (rev 1638)
@@ -140,6 +140,13 @@
     boolean enableFederation = settingsInjector.getInstance(Key.get(Boolean.class,
         Names.named(CoreSettings.ENABLE_FEDERATION)));
 
+    int listenerCount = settingsInjector.getInstance(Key.get(Integer.class,
+        Names.named(CoreSettings.LISTENER_EXECUTOR_THREAD_COUNT)));
+    int waveletLoadCount = settingsInjector.getInstance(Key.get(Integer.class,
+        Names.named(CoreSettings.WAVELET_LOAD_EXECUTOR_THREAD_COUNT)));
+    int deltaPersistCount = settingsInjector.getInstance(Key.get(Integer.class,
+        Names.named(CoreSettings.DELTA_PERSIST_EXECUTOR_THREAD_COUNT)));
+
     if (enableFederation) {
       Module federationSettings =
           SettingsBinder.bindSettings(PROPERTIES_FILE_KEY, FederationSettings.class);
@@ -150,7 +157,8 @@
     Module federationModule = buildFederationModule(settingsInjector, enableFederation);
     PersistenceModule persistenceModule = settingsInjector.getInstance(PersistenceModule.class);
     Injector injector =
-        settingsInjector.createChildInjector(new ServerModule(enableFederation),
+        settingsInjector.createChildInjector(new ServerModule(enableFederation, listenerCount,
+            waveletLoadCount, deltaPersistCount),
             new RobotApiModule(), federationModule, persistenceModule);
 
     ServerRpcProvider server = injector.getInstance(ServerRpcProvider.class);

Modified: trunk/src/main/resources/wave-server.properties
===================================================================
--- trunk/src/main/resources/wave-server.properties	2011-12-07 12:18:53 UTC (rev 1637)
+++ trunk/src/main/resources/wave-server.properties	2011-12-12 21:47:20 UTC (rev 1638)
@@ -71,11 +71,19 @@
 admin_user = @local.net
 
 # The wave id of the welcome template wave. (Without domain, for example: w+Fxjs_-ZPmmA).
-# If filled in then a copy of this wave (actually only the root blip) will be 
+# If filled in then a copy of this wave (actually only the root blip) will be
 # automatically added to the inbox of every new user.
 # Default value: "" (empty)
-welcome_wave_id = 
+welcome_wave_id =
 
+# Thread counts
+#The number of threads to listen on wavelet updates. Default value: 1
+listener_executor_thread_count = 1
+#The number of threads for loading wavelets. Default value: 2
+wavelet_load_executor_thread_count = 2
+#The number of threads to persist deltas. Default value: 2
+delta_persist_executor_thread_count = 2
+
 # To enable federation, edit the server.federation.config file and include it here.
 #include = server.federation.config
 

Modified: trunk/src/test/java/cc/kune/core/server/TestHelper.java
===================================================================
--- trunk/src/test/java/cc/kune/core/server/TestHelper.java	2011-12-07 12:18:53 UTC (rev 1637)
+++ trunk/src/test/java/cc/kune/core/server/TestHelper.java	2011-12-12 21:47:20 UTC (rev 1638)
@@ -59,16 +59,16 @@
       final PersistenceModule wavePersistModule = injector.getInstance(PersistenceModule.class);
       final NoOpFederationModule federationModule = injector.getInstance(NoOpFederationModule.class);
       final Injector childInjector = injector.createChildInjector(wavePersistModule, new ServerModule(
-          false), new RobotApiModule(), federationModule, FinderRegistry.init(new JpaPersistModule(
-          persistenceUnit)), module, new Module() {
-        @Override
-        public void configure(final Binder binder) {
-          binder.bindScope(SessionScoped.class, Scopes.SINGLETON);
-          binder.bindScope(RequestScoped.class, Scopes.SINGLETON);
-          binder.bind(KuneProperties.class).toInstance(new KunePropertiesDefault(propetiesFileName));
-          binder.bind(HttpServletRequest.class).to(HttpServletRequestMocked.class);
-        }
-      });
+          false, 1, 2, 2), new RobotApiModule(), federationModule,
+          FinderRegistry.init(new JpaPersistModule(persistenceUnit)), module, new Module() {
+            @Override
+            public void configure(final Binder binder) {
+              binder.bindScope(SessionScoped.class, Scopes.SINGLETON);
+              binder.bindScope(RequestScoped.class, Scopes.SINGLETON);
+              binder.bind(KuneProperties.class).toInstance(new KunePropertiesDefault(propetiesFileName));
+              binder.bind(HttpServletRequest.class).to(HttpServletRequestMocked.class);
+            }
+          });
       try {
         childInjector.getInstance(WaveServerImpl.class).initialize();
       } catch (final WaveServerException e) {

Modified: trunk/src/test/java/cc/kune/core/server/integration/IntegrationTestHelper.java
===================================================================
--- trunk/src/test/java/cc/kune/core/server/integration/IntegrationTestHelper.java	2011-12-07 12:18:53 UTC (rev 1637)
+++ trunk/src/test/java/cc/kune/core/server/integration/IntegrationTestHelper.java	2011-12-12 21:47:20 UTC (rev 1638)
@@ -65,8 +65,8 @@
       final Injector childInjector = injector.createChildInjector(wavePersistModule,
           FinderRegistry.init(new JpaPersistModule(TestConstants.PERSISTENCE_UNIT)),
           new ListsServerModule(), new RobotApiModule(), new PlatformServerModule(),
-          new DocumentServerModule(), new ChatServerModule(), new ServerModule(false), federationModule,
-          new WikiServerModule(), new TaskServerModule(), new BarterServerModule(),
+          new DocumentServerModule(), new ChatServerModule(), new ServerModule(false, 1, 2, 2),
+          federationModule, new WikiServerModule(), new TaskServerModule(), new BarterServerModule(),
           new EventsServerModule(), new AbstractModule() {
             @Override
             protected void configure() {

Modified: trunk/src/test/java/cc/kune/wave/server/KuneWaveServiceDefaultTest.java
===================================================================
--- trunk/src/test/java/cc/kune/wave/server/KuneWaveServiceDefaultTest.java	2011-12-07 12:18:53 UTC (rev 1637)
+++ trunk/src/test/java/cc/kune/wave/server/KuneWaveServiceDefaultTest.java	2011-12-12 21:47:20 UTC (rev 1638)
@@ -32,6 +32,7 @@
 import java.util.TreeSet;
 
 import org.junit.Before;
+import org.junit.Ignore;
 import org.junit.Test;
 import org.waveprotocol.wave.model.waveref.WaveRef;
 
@@ -57,6 +58,27 @@
   ParticipantUtils participantUtils;
 
   @Test
+  @Ignore
+  public void addAndDelMainParticipant() throws IOException {
+    doLogin();
+    final WaveRef waveletName = createTestWave();
+    assertNotNull(waveletName);
+    manager.addParticipants(waveletName, getSiteAdminShortName(), NEW_PARTICIPANT);
+
+    final Wavelet fetchWavelet = manager.fetchWave(waveletName, getSiteAdminShortName());
+    assertNotNull(fetchWavelet);
+    assertEquals(2, fetchWavelet.getParticipants().size());
+    assertTrue(manager.isParticipant(fetchWavelet, NEW_PARTICIPANT));
+    assertTrue(manager.isParticipant(fetchWavelet, getSiteAdminShortName()));
+    // Del all
+    manager.delParticipants(waveletName, getSiteAdminShortName(), getSiteAdminShortName());
+    // This fails because we don't have a way to access to than wave now ...
+    // @domain don't work neither
+    final Wavelet fetchedAfterDeleted = manager.fetchWave(waveletName, "");
+    assertNotNull(fetchedAfterDeleted);
+  }
+
+  @Test
   public void addAndDelParticipantTwice() throws IOException {
     doLogin();
     final WaveRef waveletName = createTestWave();
@@ -72,7 +94,7 @@
     assertEquals(2, fetchWavelet.getParticipants().size());
     assertTrue(manager.isParticipant(fetchWavelet, NEW_PARTICIPANT));
     assertTrue(manager.isParticipant(fetchWavelet, getSiteAdminShortName()));
-    // Del all
+    // Del main editor
     manager.delParticipants(waveletName, getSiteAdminShortName(), NEW_PARTICIPANT, NEW_PARTICIPANT,
         getSiteAdminShortName(), getSiteAdminShortName());
   }




More information about the kune-commits mailing list