/**
* 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.wave.client.wave;
import com.google.common.base.Preconditions;
import org.waveprotocol.wave.model.conversation.ConversationBlip;
import org.waveprotocol.wave.model.document.operation.DocInitialization;
import org.waveprotocol.wave.model.id.IdUtil;
import org.waveprotocol.wave.model.id.ModernIdSerialiser;
import org.waveprotocol.wave.model.id.WaveletId;
import org.waveprotocol.wave.model.util.CollectionUtils;
import org.waveprotocol.wave.model.util.StringMap;
import org.waveprotocol.wave.model.wave.data.DocumentFactory;
import org.waveprotocol.wave.model.wave.data.DocumentOperationSink;
/**
* Manages the collection of blip documents and data documents for all
* conversations in a wave, serving as a factory for new documents and a
* registry for accessing blip documents.
*
* @param <BlipDocument> the document type for blip documents
*/
public final class WaveDocuments<BlipDocument extends DocumentOperationSink>
implements DocumentFactory<DocumentOperationSink>, DocumentRegistry<BlipDocument> {
/** The factory used to create blip documents. */
private final DocumentFactory<BlipDocument> blipDocFactory;
/** The factory used to create non-blip documents. */
private final DocumentFactory<?> dataDocFactory;
/** All the blip documents, indexed by conversation id then blip id. */
private final StringMap<StringMap<BlipDocument>> blips = CollectionUtils.createStringMap();
/**
* Creates a wave's document collection.
*/
private WaveDocuments(DocumentFactory<BlipDocument> blip, DocumentFactory<?> data) {
this.blipDocFactory = blip;
this.dataDocFactory = data;
}
/**
* Creates a wave's document collection.
*
* @param blipDocFactory factory for blip documents
* @param dataDocFactory factory for data documents.
*/
public static <B extends DocumentOperationSink> WaveDocuments<B> create(
DocumentFactory<B> blipDocFactory, DocumentFactory<?> dataDocFactory) {
return new WaveDocuments<B>(blipDocFactory, dataDocFactory);
}
@Override
public DocumentOperationSink create(
final WaveletId waveletId, final String blipId, final DocInitialization content) {
String waveletIdStr = ModernIdSerialiser.INSTANCE.serialiseWaveletId(waveletId);
if (IdUtil.isBlipId(blipId)) {
BlipDocument document = blipDocFactory.create(waveletId, blipId, content);
StringMap<BlipDocument> convDocuments = getConversationDocuments(waveletIdStr);
Preconditions.checkState(!convDocuments.containsKey(blipId));
convDocuments.put(blipId, document);
return document;
} else {
return dataDocFactory.create(waveletId, blipId, content);
}
}
/**
* Gets the document map for a particular conversation.
*
* @param id conversation id
*/
private StringMap<BlipDocument> getConversationDocuments(String id) {
StringMap<BlipDocument> convDocuments = blips.get(id);
if (convDocuments == null) {
convDocuments = CollectionUtils.createStringMap();
blips.put(id, convDocuments);
}
return convDocuments;
}
@Override
public BlipDocument get(ConversationBlip blip) {
return getBlipDocument(blip.getConversation().getId(), blip.getId());
}
/**
* Reveals access to the special document implementation for conversational
* blips.
*
* @param waveletId
* @param docId
* @return the special document implementation (content-document) for the
* document, if it has one. This returns null either if the document
* does not exist, or it is a regular non-special (data) document.
*/
public BlipDocument getBlipDocument(String waveletId, String docId) {
StringMap<BlipDocument> convDocuments = blips.get(waveletId);
return convDocuments != null ? convDocuments.get(docId) : null;
}
}