/** * Copyright 2009 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.model.conversation; import org.waveprotocol.wave.model.document.Document; import org.waveprotocol.wave.model.wave.Blip; import org.waveprotocol.wave.model.wave.ParticipantId; import java.util.Set; /** * A conversational element, with content, contributors and other metadata. * * A blip may be logically deleted, but remain as a parent to non-inline reply * threads. A deleted blip is usable only as an accessor to its reply threads, * to check if it is deleted, and to attempt deletion again. If those reply * threads are subsequently removed then the blip is also removed. * * TODO(anorth): add setLastModifiedTime, addContributor, when metadata * is no longer implicit. * * @author anorth@google.com (Alex North) */ public interface ConversationBlip { /** * An value-type comprising an inline reply thread with its location. This * class is designed to be subclassed to provide a concrete thread type. * * We can't use a simple Pair for this due to restrictions in Java's generic * type matching. It should be noted that this class only provides the threads location at the * point in time the object was created. It is not updated as the document changes. */ class LocatedReplyThread<T extends ConversationThread> { private final T thread; private final int location; public static <T extends ConversationThread> LocatedReplyThread<T> of(T thread, int location) { return new LocatedReplyThread<T>(thread, location); } public LocatedReplyThread(T thread, int location) { this.thread = thread; this.location = location; } // Non-final so it may be overridden. public T getThread() { return thread; } public final int getLocation() { return location; } @Override public String toString() { return "LocatableReplyThread(" + thread + " at " + location + ")"; } @Override public final boolean equals(Object o) { if (o == this) { return true; } if (o == null) { return false; } if (o instanceof LocatedReplyThread<?>) { LocatedReplyThread<?> other = (LocatedReplyThread<?>) o; return other.thread == thread && other.location == location; } return false; } @Override public final int hashCode() { return 37 * getThread().hashCode() + new Integer(location).hashCode(); } } /** * Gets the conversation to which this blip belongs. */ Conversation getConversation(); /** * Gets the thread to which this blip belongs. */ ConversationThread getThread(); /** * Gets the reply thread with the given id. * @return null if no such thread. */ ConversationThread getReplyThread(String id); /** * Gets the inline replies to this thread, with their locations in the blip * document. The replies are presented in increasing location order (any * with invalid locations are last). * * Note that the reply locations are only valid for immediate use and must not * be stored. */ Iterable<? extends LocatedReplyThread<? extends ConversationThread>> locateReplyThreads(); /** * Gets all reply threads to this blip, in the order defined by history of * appends. */ Iterable<? extends ConversationThread> getReplyThreads(); /** * Creates a new reply thread and adds it to this blip after any existing replies. The thread * will be anchored at the end of this blip. */ ConversationThread addReplyThread(); /** * Creates a new reply thread and adds it to this blip at a specific location. * * @param location location within the blip content at which to anchor */ ConversationThread addReplyThread(int location); /** * Gets the content of this blip. */ Document getContent(); /** * Gets the participant id of the author of this blip. */ ParticipantId getAuthorId(); /** * Gets the set of contributors to the blip (this may include the author). */ Set<ParticipantId> getContributorIds(); /** * Gets the last modification timestamp of this blip. */ long getLastModifiedTime(); /** * Gets the last modification version of this blip. * * TODO(anorth,user): move conversation/blip versioning to an external * module, like read/unread. */ long getLastModifiedVersion(); /** * Clears this blip's content document and deletes all reply threads. The blip * is removed from the conversation and is no longer usable. */ void delete(); /** * Gets an id for this blip. Blip ids are unique in the scope of the * conversation. */ String getId(); /** * Checks whether this blip is the first blip of the root thread of the conversation * @return true if this is the first blip of the conversation. */ boolean isRoot(); // // Migration hacks // Blip hackGetRaw(); }