/** * 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 org.waveprotocol.box.webclient.client; import com.google.common.base.Preconditions; import com.google.gwt.user.client.Command; import org.waveprotocol.wave.client.StageOne; import org.waveprotocol.wave.client.StageTwo; import org.waveprotocol.wave.client.account.ProfileManager; import org.waveprotocol.wave.client.common.util.AsyncHolder; import org.waveprotocol.wave.concurrencycontrol.channel.WaveViewService; import org.waveprotocol.wave.model.id.IdGenerator; import org.waveprotocol.wave.model.id.WaveId; import org.waveprotocol.wave.model.schema.SchemaProvider; import org.waveprotocol.wave.model.schema.conversation.ConversationSchemas; import org.waveprotocol.wave.model.wave.ParticipantId; import org.waveprotocol.wave.model.wave.data.WaveViewData; import org.waveprotocol.wave.model.wave.data.impl.WaveViewDataImpl; /** * Provides stage 2 of the staged loading of the wave panel * * @author zdwang@google.com (David Wang) */ public class StageTwoProvider extends StageTwo.DefaultProvider { private final WaveId waveId; private final RemoteViewServiceMultiplexer channel; private final boolean isNewWave; // TODO: Remove this after WebClientBackend is deleted. private final IdGenerator idGenerator; // shared across other client components private final ProfileManager profiles; /** * Continuation to progress to the next stage. This will disappear with the * new protocol. */ private AsyncHolder.Accessor<StageTwo> whenReady; /** * @param waveId the id of the wave to open, or null to create a new wave * @param channel communication channel * @param idGenerator */ public StageTwoProvider(StageOne stageOne, WaveId waveId, RemoteViewServiceMultiplexer channel, boolean isNewWave, IdGenerator idGenerator, ProfileManager profiles) { super(stageOne); Preconditions.checkArgument(stageOne != null); Preconditions.checkArgument(waveId != null); this.waveId = waveId; this.channel = channel; this.isNewWave = isNewWave; this.idGenerator = idGenerator; this.profiles = profiles; } @Override protected SchemaProvider createSchemas() { return new ConversationSchemas(); } @Override public String createSessionId() { return Session.get().getIdSeed(); } @Override protected IdGenerator createIdGenerator() { return idGenerator; } @Override protected ParticipantId createSignedInUser() { return ParticipantId.ofUnsafe(Session.get().getAddress()); } @Override protected WaveViewService createWaveViewService() { return new RemoteWaveViewService(waveId, channel, getDocumentRegistry()); } /** * Swaps order of open and render. */ @Override protected void install() { if (isNewWave) { // For a new wave, initial state comes from local initialization. getConversations().createRoot().getRootThread().appendBlip(); super.install(); whenReady.use(StageTwoProvider.this); } else { // For an existing wave, while we're still using the old protocol, // rendering must be delayed until the channel is opened, because the // initial state snapshots come from the channel. getConnector().connect(new Command() { @Override public void execute() { // This code must be kept in sync with the default install() // method, but excluding the connect() call. // Install diff control before rendering, because logical diff state // may // need to be adjusted due to arbitrary UI policies. getDiffController().install(); // Ensure the wave is rendered. stageOne.getDomAsViewProvider().setRenderer(getRenderer()); ensureRendered(); // Install eager UI. installFeatures(); // Rendering, and therefore the whole stage is now ready. whenReady.use(StageTwoProvider.this); } }); } } @Override protected ProfileManager createProfileManager() { return profiles; } @Override protected void create(final AsyncHolder.Accessor<StageTwo> whenReady) { this.whenReady = whenReady; super.create(new AsyncHolder.Accessor<StageTwo>() { @Override public void use(StageTwo x) { // Delay progression until rendering is ready. } }); } @Override protected void fetchWave(final AsyncHolder.Accessor<WaveViewData> whenReady) { whenReady.use(WaveViewDataImpl.create(waveId)); } }