/**
* 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));
}
}